1

だから私はandroid/javaで「helloworld」アプリケーションに取り組んでいて、スポーツアプリを実行することを選択しました(これは奇妙です...私はスポーツが好きではありません...しかし何でも)。そこで、レイアウトを設定し、ユーザーが「ドリルダウン」できるようにして、野球、MLB、またはインド人のレイアウトを表示できるようにしました。ユーザーがMLBビューから「インド人」を選択したとします。タブ、場合によっては配色、背景などを更新し、「ニュース」タブと「プレーヤー」タブ(後者はチームレイアウトに固有)のデータをロードします。残念ながら、特にESPNからの無料APIが1秒あたり1回の呼び出しに制限されている場合、API呼び出しの完了に比較的時間がかかることがあります。私はすでにいくつかの重要なキャッシュを行っていますが、「インド人」の「ニュース」と「プレーヤー」の両方をロードしないことを保証する方法はありません。

したがって、私の解決策は、データ読み込みスレッドを用意することです。UIには「このデータを取得してください」と表示され、そこにあるデータに依存せずにUIが機能します。ただし、問題は、データがデータローダーから返されると(各部分が返されるときに)、UIを適切に更新または通知する方法を教えてください。私の現在の考えは次のとおりです。

UIスレッド:

OnSelectIndians()
{
  DataLoadThread.GetIndiansPlayers();
  DataLoadThread.GetIndiansNews();
  // UI stuff
}

OnPlayersLoaded(Array Players)
{
  if (layout == INDIANS_LAYOUT)  // Make sure we haven't changed layouts
  {
    foreach player in Players
      tab[PLAYERS].textview.text += player
  }
}

しかし、これは私が以前に対処しなければならなかった問題ではありません。これはそれについて行く正しい方法ですか?それとも、私が使用できるより良い/より簡単なデザインはありますか?リクエストできるすべてのタイプのデータに対して、UIスレッドに「ondatareturned」メソッドを要求するのは特に好きではありません。私の他の大まかなアイデアは、UIコードでラムダ関数を作成することです。これは、データローダーに渡され、データ読み込みスレッドで実行されます。

DataLoadThread.Queue(
    foreach player in GetIndiansPlayers()
        myView.tab[PLAYERS].textview.text += player;
);

しかし、UIと対話するスレッドが2つあるため、これはおそらくより悪いルートだと思います。何かアドバイス?

編集:さて、AsyncTaskを使用して動作させました。箱から出してすぐに、データをロードする場合(PlayerLoadTask、NewsLoadTask、StandingsLoadTaskなど)、すべてのタイプに対して新しい派生クラスを作成する必要があるという上記の問題がまだあります。また、呼び出し中にほとんどのロジックを表示することも望んでいたので、イベントコードを見ると、その動作がわかります。以下は実際の実装です-フィードバックをいただければ幸いですが、以下の最初の回答も同じように受け入れます。

抽象パブリッククラスLoadDataHelper{publicLoadDataHelper(DataLoader dl、Object param){mDataLoader = dl; mParam = param; }

    abstract public LinkedList<String> LoadData();
    protected DataLoader mDataLoader;
    protected Object mParam;
}

abstract public class UpdateUIHelper {
    public UpdateUIHelper(MyActivity context) {
        mContext = context;
    }

    abstract public void UpdateUI(LinkedList<String> results);
    protected MyActivity mContext;
}

private class LoadDataTask extends AsyncTask<Void, Void, LinkedList<String> >   {
    private LoadDataHelper mLdh;
    private UpdateUIHelper mUih;

    LoadDataTask(LoadDataHelper ldh, UpdateUIHelper uih) {
        mLdh = ldh;
        mUih = uih;
    }

    @Override
    protected LinkedList<String> doInBackground(Void... params) {
        return mLdh.LoadData();
    }

    @Override
    protected void onPostExecute(LinkedList<String> results) {
        mUih.UpdateUI(results);
    }
}

//
// .....
// 

    LoadDataTask task = new LoadDataTask(new LoadDataHelper(mDataLoader, "football") {
                                            public LinkedList<String> LoadData() {                                                  
                                                return mDataLoader.LoadLeaguesFromSport((String)mParam);
                                            }
                                        }, 
                                        new UpdateUIHelper(this) {
                                            public void UpdateUI(LinkedList<String> results) {
                                                TextView tv = (TextView)findViewById(R.id.tv1);
                                                tv.setText("");
                                                for (String res : results) {
                                                    tv.append(res + "\n");  
                                                }
                                            }
                                        });
    task.execute();
4

5 に答える 5

3

を見てみましょう:

1)AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html

AsyncTask.onPostExecuteはUIスレッドで実行されます。これは、バックグラウンド処理を行うための最も一般的な手法だと思います。

2)runOnUIThread:独自のワーカースレッドを管理している場合は、これをワーカースレッドで使用して、コードがUIスレッドで実行されていることを確認できます。

于 2012-07-11T06:10:29.547 に答える
3

UIスレッドでUIを動作させ、非UIスレッドで非UIを動作させる方が常に優れていますが、これはAndroidにHoneyCombが登場してから法律になりました。

Androidでそれを行う2つの方法。

1.ハンドラーでJavaスレッドを使用します。 プロセスの重いバックグラウンドタスクを実行するスレッドを作成し、ハンドラーを使用してデータを表示します。

2.Android用に特別に設計されたAsyncTask<>を使用して、UI作業と非UI作業を同期します。AsyncTaskは、痛みのないスレッドとしても知られています。

于 2012-07-11T06:29:03.987 に答える
2

これAsyncTaskが設計されたものです。これが私が学んだチュートリアルです。

これがあなたがすることです

  • 拡張するクラスを作成するAsyncTask
  • 実装doInBackgroundonPostUpdateメソッド
  • uiを更新するonPostUpdateメソッドでは、runOnUiThreaduiの更新中の問題を回避するために使用できます

非同期タスクを使用するこの利点は、進行状況を更新し、ユーザーに視覚的なインジケーターを表示することもできることです。必要に応じて、タスクを簡単にキャンセルして読み込みを停止できます。

AsyncTaskは本質的に、スレッドの使用を簡素化するヘルパーです。

于 2012-07-11T06:27:30.033 に答える
1

最善の策は、AsyncTaskを使用することです。画像をダウンロードするためにサーバーに25回以上電話をかける同様のアプリを作成しました。AsyncTaskを使用すると、その時間が大幅に短縮され、優れたユーザーエクスペリエンスが提供されます。AsyncTaskの使用/設定方法に関する優れたチュートリアルは次のとおりです。

http://www.peachpit.com/articles/article.aspx?p=1823692&seqNum=3

于 2012-07-11T06:18:33.443 に答える
1

非同期タスクはあなたのための解決策です ここにチュートリアルがあります

于 2012-07-11T06:20:05.780 に答える