2012-07-13 62 views
1

创建我有一个应用程序,它要求数据在互联网上(客户端 - 服务器应用程序)的信息,但这种交流是非常缓慢的,因此,我决定创建一个的AsyncTask来管理的延迟。 在doInBackground里面,我打电话给Looper.prepare(),然后是我的“视图生成器(它可以检索数据)”。只有一条环线可以每个线程

详细(问题):

我有dinamically创建列表视图的行的活性。但每次我尝试充气行的时候,Android抛出一个活套例外“只有一条环线可以每个线程创建”

我遵循的步骤:

  • 电话Looper.preapare()
  • 使用第一inflaction创建我的名单
  • 的容器,使用第二inflaction创建列表行

我想我不能夸大两次,但我不知道我可以解决

的AsyncTask

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); 
    } 
} 
} 

processAct()以这种方式

@Override protected View processAct() throws Exception { 

    Bundle bundle = getIntent().getExtras(); 
    User user = (User)bundle.getSerializable("user"); 

    Team team = Team.getTeamInformation(this,user.getTeamId()); 
    ArrayList<Player> players =Player.getPlayerList(this,user.getTeamId()); 

    PlayersListAdapter view = new PlayersListAdapter(this,players,team); 
    return view; 
} 

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); 
} 

最后PlayerRowListAdapter延伸BaseAdapter,......这里的第二个通货膨胀

@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 ......一切工作正常...(显然没有列表)

问候

附:对不起,我的英语

+0

代码请,我们不知道你到底做了:) – Martze 2012-07-13 12:34:47

+0

代码添加,谢谢... – Ging3r 2012-07-13 13:23:21

+0

我想你应该,因为chrulri他回答说,检索doInBackground内容( ),然后在onPostExecute()或onProgressUpdate()中膨胀。我#m想知道为什么它不会崩溃的第一次膨胀.... – Martze 2012-07-13 13:48:07

回答

0

以下是我工作围绕这一点。

随着Developer Reference for AsyncTask说, doInBackground创建一个新的线程来管理它(这迫使我打电话Looper.prepare()),而onPostExecute()使用主线程。

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

我已经把第一个方法放入doInBackground(),第二个放入onPostExecute()

0

的唯一原因,你需要调用Looper.prepare()Looper.loop()是当你想在一个线程不是UI线程有一个消息Handler。基本上,它保持线程永久存活,以便线程内部创建的Handler仍然可以发送和接收消息。回调方法也是如此,如LocationListener或类似的东西。你负责时,它是通过调用Looper.getMyLooper().quit()线程,它在内部完成注销线程。

如果您正在膨胀UI线程中的观点,那么你就需要调用Looper.prepare()Looper.loop(),因为这已经是在后台完成。你不应该在UI线程之外膨胀Views

4

而不是仅仅调用Looper.prepare();,首先检查您的线程是否已经存在Looper,如果没有,则调用该函数。就像这样:

if (Looper.myLooper()==null) 
    Looper.prepare(); 
相关问题