14

スレッドを実行するAsyncTaskメイン アクティビティ ( ) 内で使用されるように作られているかどうか疑問に思っていました。MainActivity.java

たとえば、独立したファイルを作成するのではなく、をAsyncTask拡張するメインクラス内でプライベートクラスを宣言する( )を使用する場合、多くのチュートリアルに気付きました。Activity.javaAsyncTaskMyAsyncTask.javaclass

しかし、独立したファイルを使用する場合、 () はクラスrunOnUIThreadに属しているため実行できないことに気付きました。ActivityAsyncTaskAsyncTaskActivity

4

4 に答える 4

15

それはまったく問題ありません。私はよくやりますが、使い方次第です。他の人が使用する可能性がある場合はActivities、独自のクラスまたは共有クラスにします。しかし、それが単一の目的のためであれば、私はそれを の内部クラスにしMainActivityます。

内部クラスにする利点は、そのクラスのメンバー変数に直接アクセスできることです。別のクラスにする場合、またはその他の変数paramsなどを渡す必要がある場合は、コンストラクターを作成するだけです。context

あなたが何をしているのか正確にはわかりませんが、必要かどうかはわかりませんrunOnUiThread()AsyncTaskファイルにコンストラクターを作成し、それをcontextパラメーターとして受け入れ、その他必要なものを何でも受け入れることができます。UI次に、で更新できますonPostExecute()

public class MyAsyncTask extends AsyncTask{

    private Context context; 

    public MyAsyncTask(Context context) {  // can take other params if needed
        this.context = context;
    }

    // Add your AsyncTask methods and logic
    //you can use your context variable in onPostExecute() to manipulate activity UI
}

それをあなたのMainActivity

MyAsyncTask myTask = new MyAsyncTask(this);  //can pass other variables as needed
myTask.execute();
于 2013-03-14T12:59:36.650 に答える
8

通常、AsyncTask同じアクティビティでのみ使用されることをより明確にするために、同じクラスに配置します。

AsyncTaskそれを複数のアクティビティで再利用したい場合は、独立したクラスを作成し、コンストラクターによってアクティビティからパラメーターを渡すだけです。

以下のように AsyncTask からアクティビティに応答を送信し、必要に応じてリスナー メソッドを呼び出すために、AsyncTask にインターフェイスを作成できます。私はそれを呼んだonPostExecute()

public class DeckDownloader extends AsyncTask<Void, Void, String> {

    OnDownloadUpdateListener listener;
    
    public interface OnDownloadUpdateListener {
         public void OnDownloadDeckFinish(String Response);     
    }


    public DeckDownloader(Context ctx, OnDownloadUpdateListener listener) {
         mContext = ctx;
         this.listener = listener;
    }

    @Override
    protected String doInBackground(Void... params) {
         String str = "downloading";
         //your async code goes here
         return str;
    }

     @Override
     protected void onPreExecute() {
          super.onPreExecute();
     }

     @Override
     protected void onPostExecute(String result) {
          if( listener != null ) {
                listener.OnDownloadDeckProgress(result);
          }
     }
}

Your Activity クラスでは、そのリスナーを実装し、その実装メソッドで textview を更新するコードを記述する必要があります。

    public class myActivity extends Activity{
          private DeckDownloader.OnDownloadUpdateListener downloadListener;
          TextView txtAsyncResponse;

          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              txtAsyncResponse = (TextView) findViewById(R.id.txtAsyncResponse);
    

            downloadListener = new DeckDownloader.OnDownloadUpdateListener() {
               @Override
               public void OnDownloadDeckFinish(String Response) {
                    txtAsyncResponse.setText(Response);
               }
            };
    }

また、以下のコードを記述して、ボタン クリック イベントなどの必要なときにいつでもアクティビティで AsyncTask を開始できます。

 DeckDownloader mTask = new DeckDownloader(this.getApplicationContext(), downloadListener);
 mTask.execute();

これはあなたが望むものです!

于 2013-03-14T13:05:00.197 に答える
2

ほとんどのチュートリアルでは、実際に最高のものではなく、理解/読みやすいものを選択していると思います。

内部クラスを使用すると、アクティビティの変数を利用できるように保つことができます。これにより、より簡単になります。

一般に、AsyncTasksも可能な限りカプセル化して、コード内の他のポイントから再利用できるようにする必要があります。

于 2013-03-14T13:00:10.223 に答える
2

はい。で作成できAsyncTask classますMainActivity.java

public class CategoryListScreen extends Activity {


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new loadcategory().execute();
    }

    class loadcategory extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) { }
        protected void onPostExecute(Void param) { }
    } // AsyncTask over
}//main class over
于 2013-03-14T13:01:45.337 に答える