2012-07-13 19 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();