2

基本的に、実行したいコードをdoInBackground内の別のスレッドに配置する必要がありますか、それともdoInBackground内の別の関数/クラス/whatever-it-is-functions-are-called-in-JAVAを呼び出して非同期で実行できますか?IE :(オンラインで見つけたサンプルコード)

      protected String doInBackground(String... params) {
        for(int i=0;i<5;i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText("Executed");
        return null;
  }  

これは私がそれが行われたのを見た方法ですが、代わりに私は行うことができます:

      protected String doInBackground(String... params) {
           postToServer(x,y,z,h);
      }  

すでに作成した関数を呼び出して、その関数を別のスレッドで実行しますか?HTTPサーバーの応答が少し遅い場合があり(現時点ではテストが不十分なサーバーです)、postToServer()の呼び出しに5秒以上かかると、Androidは自動的にkillプロセスボックスをポップアップし、UIが無効になるまでpostToServer()呼び出しが終了します。これは、GPS追跡アプリ(私が働いている会社の内部)を開発していて、追跡をオフにするUIオプションが、postToServer()が終了するまでフリーズするため、問題になります。これが回答された場合はお詫び申し上げます。検索してみましたが、この機能を実現するために期待している方法で機能する例は見つかりませんでした。

4

4 に答える 4

3

onPostExecuteそれは可能ですが、UIスレッドで実行されるため、UIの更新をに移動する必要があります。

public MyAsyncTask extends AsyncTask<foo, bar, baz> {

    ...

    protected String doInBackground(String... params) {
       postToServer(x,y,z,h);
    }  

    protected void onPostExecute(Long result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText("Executed");
    }

    ....

}

TextViewをのコンストラクターに渡しAsyncTask、WeakReferenceとして格納することもできます。プライベート最終WeakReferencetextViewReference;

public MyAsyncTask(TextView txt) {
    textViewReference = new WeakReference<TextView>(txt);
}

次に、onPostExecuteで、TextView参照がまだ存在していることを確認します。

protected void onPostExecute(Long result) {
    TextView txt = textViewReference.get();
    if (txt != null)
        txt.setText("Executed");
}

タスクが実行されていることをユーザーに通知したい場合は、を呼び出す前にそれを配置しAsyncTaskます。

 myTextView.setText("Update in progress...");
 new MyAsyncTask().execute();

次に、「更新が完了しました」と言うようにonPostExecute設定します。TextView

于 2012-11-26T22:53:55.140 に答える
1

2番目の方法で試しましたか?

あなたが投稿したものから、それはあなたが2番目の例でそれを持っている方法でうまくいくはずであるように思われます。

ただし(おそらくあなたの質問とは関係ありませんか?)最初の例では、バックグラウンドスレッドからUIを変更しようとしているため、失敗すると思います。TextViewを操作するパーツを、onPostExecute()ではなく内部に配置する必要がありますdoInBackground()

于 2012-11-26T22:54:12.850 に答える
1

はい、できます。postToServerメソッドの呼び出し(Javaでの名前)はメインスレッドから実行されます。doInBackgroundのメソッド内のすべてAsyncTaskはプールされたスレッドで実行されますが、直接呼び出さないようにしてください。execute代わりにasynktaskを呼び出してください。Androidフレームワークが自動的に作業を行い、doInBackground別のスレッドで実行されます。

次のようなことを試してください。

new AsyncTask<Void, Void, Void>() {
    @Override
    // this runs on another thread
    protected Void doInBackground(Void... params) {
        // assuming x, y, z, h are visible here
        postToServer(x, y, z, h);
        return null;
    }

    @Override
    // this runs on main thread
    protected void onPostExecute(Void result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText("Executed");
    }

}.execute(); // call execute, NOT doInBackGround

また、メインスレッドで実行するAsyncTaskなど、他のすべての方法に注意しonPostExecuteてください。そのため、それらに大きな負荷をかけないようにしてください。

于 2012-11-26T22:59:31.593 に答える
-1

基本的に、結論はdoInBackground()メソッドがUiスレッドまたはメインスレッドと対話できないことです。そのため、doInBackground()でTextViewを操作しようとすると、UIスレッドがクラッシュします。これは違法です。したがって、UIスレッドと対話する場合は、doInBackgroundで作業しているときに、OnPostExecute()をオーバーライドする必要があります。//この関数は、doInBackground関数ジョブが完了したときに呼び出されます。したがって、ジョブがdoInBackground()で実行されているとき、またはdoInBackground()で実行されているときに、これによってUIスレッドコンテンツを更新できます。

于 2019-09-19T10:45:58.813 に答える