Android 每个线程只能创建一个活套

Android 每个线程只能创建一个活套,android,android-asynctask,Android,Android Asynctask,我有一个在internet上请求数据信息的应用程序(客户机-服务器应用程序),但这种通信非常缓慢,因此我决定创建一个异步任务来管理延迟。 在doInBackground内部,我调用Looper.prepare()然后调用我的“视图生成器(它检索数据)” 详细说明(问题): 我有一个活动,它以友好方式创建列表视图的行。但每次我尝试膨胀行时,android都会抛出一个循环器异常“每个线程只能创建一个循环器” 我遵循以下步骤: 调用Looper.prepare() 使用第一次充气创建我的列表的容器

我有一个在internet上请求数据信息的应用程序(客户机-服务器应用程序),但这种通信非常缓慢,因此我决定创建一个异步任务来管理延迟。 在doInBackground内部,我调用
Looper.prepare()
然后调用我的“视图生成器(它检索数据)”

详细说明(问题):

我有一个活动,它以友好方式创建列表视图的行。但每次我尝试膨胀行时,android都会抛出一个循环器异常“每个线程只能创建一个循环器”

我遵循以下步骤:

  • 调用
    Looper.prepare()
  • 使用第一次充气创建我的列表的容器
  • 使用第二次充气创建列表行
我想我不能充气两次,但我不知道如何解决这个问题

异步任务

private class DrawerView extends AsyncTask<ActivityGroup, String, View>{
    Exception exc=null;     

    @Override protected void onPreExecute() {
    super.onPreExecute();   
}

@Override protected View doInBackground(ActivityGroup... params) {
    try {
        Looper.prepare();
    return processAct();
    }catch (ConnectionException e) {    
        exc =e;
    return null;                
    }
    catch (Exception e) {
        exc = e;
    return null;
    }
}

@Override protected void onPostExecute(View result) {
    super.onPostExecute(result);
    if(exc!= null){
        Utils.usrMessage(getApplicationContext(), "Oh Noo!:\n"+exc.getMessage());
        Utils.logErr(getApplicationContext(), exc);
    finish();
    }
    if(result!= null){
        setContentView(result);
    }
}
}
PlayerListAdapter
是构建/设置第一个视图(列表容器)的类…这里是第一个视图

public PlayersListAdapter(Context context, ArrayList<Player> players,Team team) throws Exception{
    super(context);
    View view = inflate(getContext(), R.layout.team_players, this);

    TextView tv_teamName = (TextView)view.findViewById(R.id.tbplrs_tmnm);
    TextView tv_playersNum = (TextView)view.findViewById(R.id.tbplrs_nplrs);

    tv_teamName.setText(team.getName());

    String msg = players.size()+" ";
    msg += (players.size()!=1)?context.getString(R.string.playerPlural):context.getString(R.string.playerSingle);
    tv_playersNum.setText(msg);

    ListView lView = (ListView)view.findViewById(R.id.tbplrs_plrslst);
    PlayersRowListAdapter plAdapter = new PlayersRowListAdapter(context, players);
    lView.setAdapter(plAdapter);
} 
@Override public View getView(int position, View view, ViewGroup parent) {
    if (view == null){
        LayoutInflater lInflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = lInflator.inflate(R.layout.team_player_singlplayer,null);
    }
    ....
    ....
}
注意:如果我放下第二个适配器
PlayerRowListAdapter
…一切正常…(显然没有列表)

问候


p、 美国。对不起,我的英语是

您需要调用
Looper.prepare()
Looper.loop()
的唯一原因是您希望在非UI线程中有消息处理程序。基本上,它使线程永远处于活动状态,这样在线程内部创建的
处理程序仍然可以发送和接收消息。类似于
LocationListener
或类似的回调方法也是如此。通过在线程所在的线程内调用
Looper.getMyLooper().quit()
,可以终止线程


如果在UI线程中扩展视图,则不需要调用
Looper.prepare()
Looper.loop()
,因为这已经在后台完成。决不能在UI线程外膨胀
视图。

调用
Looper.prepare()
Looper.loop()
的唯一原因是当您希望在非UI线程中有消息
处理程序时。基本上,它使线程永远处于活动状态,这样在线程内部创建的
处理程序仍然可以发送和接收消息。类似于
LocationListener
或类似的回调方法也是如此。通过在线程所在的线程内调用
Looper.getMyLooper().quit()
,可以终止线程


如果在UI线程中扩展视图,则不需要调用
Looper.prepare()
Looper.loop()
,因为这已经在后台完成。您不应该在UI线程之外膨胀
视图。

AsyncTask已经有了自己的
活套。如果要从
doInBackground()
方法更新UI,请使用该方法,然后在主线程中调用。在
onProgressUpdate
中,您可以放大视图并将其添加到UI中


编辑:示例代码:

AsyncTask已经有了自己的
活套。如果要从
doInBackground()
方法更新UI,请使用该方法,然后在主线程中调用。在
onProgressUpdate
中,您可以放大视图并将其添加到UI中


编辑:示例代码:

以下是我如何解决这个问题的

正如《圣经》所说,
doInBackground
创建一个新线程来管理它(这迫使我调用
Looper.prepare()
),而
onPostExecute()
使用主线程

所以我将
processAct()
分为两种方法:检索数据的
prepareData()
和调用适配器的
createView()


我将第一个方法放入
doInBackground()
,将第二个方法(
createView()
)放入
onPostExecute()
,以下是我如何解决这个问题的

正如《圣经》所说,
doInBackground
创建一个新线程来管理它(这迫使我调用
Looper.prepare()
),而
onPostExecute()
使用主线程

所以我将
processAct()
分为两种方法:检索数据的
prepareData()
和调用适配器的
createView()


我将第一个方法放入
doInBackground()
,将第二个方法(
createView()
)放入
onPostExecute()
,而不是只调用
Looper.prepare(),首先检查线程的活套是否不存在,如果不存在,则调用该函数。像这样:

if (Looper.myLooper()==null)
    Looper.prepare();

而不仅仅是调用
Looper.prepare(),首先检查线程的活套是否不存在,如果不存在,则调用该函数。像这样:

if (Looper.myLooper()==null)
    Looper.prepare();

请编码,我们不知道您到底做了什么:)我认为您应该,正如chrulri在回答中所说的,检索doInBackground()中的内容,然后在onPostExecute()或onProgressUpdate()中充气。我想知道为什么它在第一次充气时没有崩溃……啊……我不知道……我的应用程序中有很多“页面”,只有列表视图的页面(然后是两次充气的页面)会崩溃,只有这个例外……但是,我决定……;),现在发布我的解决方案…谢谢你的帮助!!!请编码,我们不知道您到底做了什么:)我认为您应该,正如chrulri在回答中所说的,检索doInBackground()中的内容,然后在onPostExecute()或onProgressUpdate()中充气。我想知道为什么它在第一次充气时没有崩溃……啊……我不知道……我的应用程序中有很多“页面”,只有列表视图的页面(然后是两次充气的页面)会崩溃,只有这个例外……但是,我决定……;),现在发布我的解决方案…谢谢你的帮助!!!