39

私はインナークラスが嫌いです。

「短命」の AsyncTask を起動する主なアクティビティがあります。

AsyncTask は別のファイルにあり、メイン アクティビティの内部クラスではありません

非同期タスクがメイン アクティビティから textView を更新する必要があります。

AsyncTask が内部クラスの場合、onProgressUpdate から TextView を更新できることはわかっています。

しかし、外部の独立した非同期タスクからはどうですか?

更新:これは機能しているように見えます:

アクティビティでは、タスクを呼び出します

backgroundTask = new BackgroundTask(this);
backgroundTask.execute();

私が持っているコンストラクターで

public BackgroundTask(Activity myContext)
{
    debug = (TextView) myContext.findViewById(R.id.debugText);
}

ここで、debug は AsyncTask のプライベート フィールドでした。

だから onProgressUpdate 私はできる

debug.append(text);

ご提案いただきありがとうございます

4

7 に答える 7

40

AsyncTask は常に とは別のクラスActivityですが、アクティビティ クラス ファイルとは別のファイルにあると思われるため、アクティビティの内部クラスであることから利益を得ることができません。Activity コンテキストを引数として Async Task (つまり、そのコンストラクター) に渡すだけです。

class MyAsyncTask extends AsyncTask<URL, Integer, Long> {

    WeakReference<Activity> mWeakActivity;

    public MyAsyncTask(Activity activity) {
       mWeakActivity = new WeakReference<Activity>(activity);
    }

 ...

必要なときに使用します( during で使用しないことを忘れないでdoInBackground()ください)つまり、通常呼び出すときに使用します

int id = findViewById(...)

AsyncTask で ie を呼び出す

Activity activity = mWeakActivity.get();
if (activity != null) {
   int id = activity.findViewById(...);
}

が進行Activity中になくなる可能性があることに注意してください(したがって、返される参照は になる可能性があります) が、使用しても GC がそれを収集 (およびメモリリーク) するのを防ぐことはできません。状態 (それでも、ロジックによっては、内部状態の変更や DB の更新などを実行したい場合がありますが、UI に触れることはスキップする必要があります)。doInBackground()nullWeakReference

于 2012-09-03T18:44:52.010 に答える
25

インターフェイスの使用 1) インターフェイスを 1 つ作成する

public interface OnDataSendToActivity {
    public void sendData(String str);
}

2)アクティビティに実装します

public class MainActivity extends Activity implements OnDataSendToActivity{

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          new AsyncTest(this).execute(new String[]{"AnyData"}); // start your task
     }

     @Override
     public void sendData(String str) {
         // TODO Auto-generated method stub

     }

}

3) AsyncTask(Activity activity) にコンストラクタを作成する{} AsyncTask ファイルに Interface を登録し、以下のように Interface メソッドを呼び出します。

public class AsyncTest extends AsyncTask<String, Integer, String> {

    OnDataSendToActivity dataSendToActivity;
    public AsyncTest(Activity activity){
        dataSendToActivity = (OnDataSendToActivity)activity;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        dataSendToActivity.sendData(result);
    }

}

ここで、OnPostExecute は、AsyncTask によってすべてのタスクが完了した後に呼び出され、doInBackground(){ return "";} によって返されるパラメーターとして「結果」を取得します。

while "dataSendToActivity.sendData(result);" アクティビティのオーバーライドされたメソッド「public void sendData(String str) {}」を呼び出します。

覚えておくべき極端なケース: を必ず渡しthisます。つまり、現在のアクティビティのコンテキストをに渡し、アクティビティのAsyncTask別のインスタンスを作成しないでください。そうしないと、アクティビティActivityが破棄され、新しいインスタンスが作成されます。

于 2014-07-03T11:31:25.427 に答える
4

アクティビティ クラスで静的関数を作成してコンテキストを渡し、テキスト ビューを更新してから、AsynkTask クラスでこの関数を呼び出して更新します。

Activity クラス: public static void updateTextView(){

//ここにあなたのコード}

AynckTask クラスでこの関数を呼び出します。

于 2012-09-03T18:53:31.707 に答える
3

この種のシナリオのために、AsyncTask の小さな拡張機能を作成しました。AsyncTask を別のクラスに保持できますが、タスクの完了への便利なアクセスも提供します。

public abstract class ListenableAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result>{

    @Override
    protected final void onPostExecute(Result result) {
        notifyListenerOnPostExecute(result);
    }

    private AsyncTaskListener<Result> mListener;
    public interface AsyncTaskListener<Result>{
        public void onPostExecute(Result result);
    }
    public void listenWith(AsyncTaskListener<Result> l){
        mListener = l;
    }
    private void notifyListenerOnPostExecute(Result result){
        if(mListener != null)
            mListener.onPostExecute(result);
    }

}

したがって、最初に AsyncTask の代わりに ListenableAsyncTask を拡張します。次に、UI コードで具体的なインスタンスを作成し、listenWith(...) を設定します。

于 2012-09-03T18:54:54.853 に答える
3

コンストラクターでコンテキスト (アクティビティなど) を AsyncTask に渡し、onSuccess または onProgressUpdate でコンテキストで必要なものを呼び出します。

于 2012-09-03T18:41:50.503 に答える
2

質問はすでに回答されていますが、まだどのように行うべきかを投稿しています..

メインアクティビティ クラス

  public class MainActivity extends Activity implements OnClickListener
    {

        TextView Ctemp;

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Ctemp = (TextView) findViewById(R.id.Ctemp);
            doConv = (Button) findViewById(R.id.doConv);
            doConv.setOnClickListener(this);
        }

        @Override
        public void onClick(View arg0) // The conversion to do
        {
            new asyncConvert(this).execute();
        }
    }

今非同期クラスに

public class asyncConvert extends AsyncTask<Void, Void, String>
{
    SoapPrimitive response = null;
    Context context;

    public asyncConvert(Context callerclass)
    {
        contextGUI = callerclass;
    }
.
.
.
.
protected void onPostExecute(String result)
    {
        ((MainActivity) contextGUI).Ctemp.setText(result); // changing TextView
    }
}
于 2013-10-15T18:32:04.073 に答える
1
    /**
     * Background Async Task to Load all product by making HTTP Request
     * */
     public  static class updateTExtviewAsyncTask extends AsyncTask<String, String, String> {

        Context context;
        ProgressDialog pDialog;
        String id, name;

        String state_id;

        //--- Constructor for getting network id from asking method

        public  updateTExtviewAsyncTask(Context context,String id,String city) 
        {
            context   = context;
            state_id  = id;
            city_name = city;
        }       
        /* *
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() 
        {
            super.onPreExecute();
            pDialog = ProgressDialog.show(context, "","Please wait...", true, true);
            pDialog.show();

        }

        /**
         * getting All products from url
         * */
        protected String doInBackground(String... args) 
        {
            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
            protected void onPostExecute(String file_url)  {

                     YourClass.UpdateTextViewData("Textview data");
        }
    }

// このコードをアクティビティ クラス内に配置し、textview static の更新を宣言します

    public static void  UpdateTextViewData(String tvData) 
{
   tv.setText(tvData);
}
于 2014-07-03T10:24:20.857 に答える