1

インターネット上でデータ情報を要求するアプリ (クライアント サーバー アプリ) がありますが、この通信は非常に遅いため、遅延を管理するために AsyncTask を作成することにしました。doInBackground の内部でLooper.prepare()、「ビュー ジェネレーター (データを取得する)」を呼び出します。

詳細に(問題):

リスト ビューの行を動的に作成するアクティビティがあります。しかし、行を膨らませようとするたびに、アンドロイドは「スレッドごとに作成できるルーパーは1つだけです」というルーパー例外をスローします

私は次の手順に従いました:

  • 電話Looper.preapare()
  • 最初のインフレを使用して、リストのコンテナを作成します
  • 2 番目のインフレーションを使用してリスト行を作成する

2回膨らませることはできないと思いますが、それを解決する方法がわかりません

非同期タスク

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 を拡張します...ここで 2 番目のインフレーション

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

注意: 2 番目のアダプターをドロップするとPlayerRowListAdapter...すべて正常に動作します... (明らかにリストなし)

よろしく

ps私の英語でごめんなさい

4

4 に答える 4

4

を呼び出すだけでなくLooper.prepare();、最初に Thread の Looper がまだ存在しないかどうかを確認し、存在しない場合はその関数を呼び出します。このような:

if (Looper.myLooper()==null)
    Looper.prepare();
于 2016-02-07T03:37:17.877 に答える
0

これが私がこれを回避した方法です。

AsyncTaskの開発者リファレンスが言うように 、メイン スレッドを使用しながら、doInBackgroundそれを管理するために新しいスレッドを作成します (これにより、 を呼び出す必要がありました)。Looper.prepare()onPostExecute()

そこで、データを取得するメソッドとアダプタを呼び出すprocessAct()メソッドの 2 つのメソッドに分割しました。prepareData()createView()

最初のメソッドを に入れ、doInBackground()2 番目のメソッド ( createView()) を に入れましたonPostExecute()

于 2012-07-13T15:09:45.710 に答える
0

Looper.prepare()andを呼び出す必要がある唯一の理由は、UI スレッドではないスレッドにLooper.loop()メッセージを入れたい場合です。基本的に、スレッド内で作成された が引き続きメッセージを送受信できるHandlerように、スレッドを永久に存続させます。Handlerなどのコールバック メソッドについても同じことが言えますLocationListener。スレッドが含まれているスレッド内で呼び出すことによって、スレッドが終了したときにスレッドを強制終了する責任がありLooper.getMyLooper().quit()ます。

UI スレッドでビューをインフレートする場合は、Looper.prepare()orを呼び出す必要はありませんLooper.loop()。これはバックグラウンドで既に行われているためです。ViewsUI スレッドの外で決してインフレートしないでください。

于 2012-07-13T12:37:32.697 に答える
0

AsyncTask には既に独自のLooper. UI をメソッドから更新する場合は、メイン スレッドで呼び出すdoInBackground()メソッドを使用します。ビューを拡張して UI に追加できます。publishProgress(..)onProgressUpdate(..)onProgressUpdate

編集: コード例: http://developer.android.com/reference/android/os/AsyncTask.html

于 2012-07-13T12:38:18.813 に答える