Android: 在 AsyncTask 中吐司

Android: toast inside AsyncTask

我有一个从 Activity QuizMap 调用的 AsyncTask class SearchForQuestions。在 SearchForQuestions 中循环遍历数组时,我无法在 AsynTask 中找到正确的 toast 上下文。

标准Toast.makeText(getApplicationContext(), "This is Toast!!!", Toast.LENGTH_SHORT).show();给出错误getApplicationContext()未定义。

我已经尝试了 SO 提供的一些解决方案,其中大部分都已列出 here 并且关注在其上获取 UiThread 和 运行。

但是我无法让它工作。这是我尝试过的示例代码片段。我在 QuizMap 中放置了一个方法并尝试从 SearchForQuestions 调用它,但无法识别 SearchForQuestions。我该如何解决这个问题? )还是java的新手...)

// QuizMap activity

public class QuizMap extends FragmentActivity 
implements OnMarkerClickListener {

private GoogleMap map;

private static final String TAG = "QuizMap"; // debugging
...

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_quizmap);
     map = ((SupportMapFragment)  getSupportFragmentManager().findFragmentById(R.id.map))
               .getMap();
...
}

    // make toast inside AsyncTask
public void showNotNearToast(final String toast) {
    QuizMap.this.runOnUiThread(new Runnable() {
        public void run() {
            Toast.makeText(QuizMap.this, "This is Toast!!!", Toast.LENGTH_SHORT).show();

        }});
}

.

// SearchForQuestions class
private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
    // checks for proximity to question locations

    Location location = 
            locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    @Override
    protected DataHandler doInBackground(String... pointsList) {
        String result = pointsList[0];
        ...
}

    @Override
    protected void onPostExecute(DataHandler result) {

        ArrayList<String> resultsArray = result.results;
        Integer numPoints = resultsArray.size();
        for (int i =0;i<numPoints;i++){

            String[] pointDetails = resultsArray.get(i).split("::");
            ...

            // we can make use of the Android distanceTo function to calculate the distances
            float distance = location.distanceTo(fixedLoc);

            if (i > DIST) { // this is UCL

                showNotNearToast("My Message"); // showNotNearToast undefined 


                if (distance < DIST) {

             ...
                 }
                    };

将 activity 传递给 AsyncTask。见下文。

private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
    Activity activity;
    public void SearchForQuestions(Activity activity){
        this.activity = activity;
    }
//... rest of the code

  public class QuizMap extends FragmentActivity implements OnMarkerClickListener {
    /*...*/
    new SearchForQuestions(this).execute();
    /*...*/
    /*When calling the toast:*/
Toast.makeText(this.activity, "This is Toast!!!", Toast.LENGTH_SHORT).show();

Just Toast it,为什么要为它创建一个函数? onPostExecute() 已经在 UI 线程上。

您无法访问,因为内部 Class 无法调用外部 class 的函数,除非您传递外部 class.

的实例
  1. onPostExecute
  2. 中祝酒
  3. 创建回调接口。

public interface ToastCallback {
    public void invoke(String text);
}

你的 AsyncTask 构造器

private ToastCallback toastCallback;
public SearchQuestions(ToastCallback callback) {
    this.toastCallback = callback;
}

// in doInBackground() {

      toastCallback.invoke("Toast from background");
 }

在你的Activity,

private void showNotNearToast(String text) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
        }
   }); 
}

public class MyToastCallback implements ToastCallback {
     @Override
     public void invoke(String text) {
         showNotNearToast(text);
     }
}

// Asynctask call
new SearchQuestion(new MyTosatCallback()).execute(<Your params here>);

在你的 AsyncTask 中试试这个:

myActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});

你在哪里

showNotNearToast("My Message"); // showNotNearToast undefined

myActivity 替换为您的 Activity。

(Ab)使用 publishProgress 方法

private class ToastAsyncTask extends AsyncTask<Void, String, Void>{
        @Override
        protected Void doInBackground(Void... voids) {
            SystemClock.sleep(1000);
            publishProgress("Toast msg string");
            SystemClock.sleep(1000);
            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            Toast.makeText(getApplicationContext(), values[0], Toast.LENGTH_SHORT).show();
        }
    }

**更新:**由于您出于某种原因遇到上下文问题,请使用此版本。艰难的上述实施对我有用。

private class ToastAsyncTask extends AsyncTask<Void, String, Void> {

        private WeakReference<Context> contextRef;

        public ToastAsyncTask(Context context) {
            contextRef = new WeakReference<Context>(context);
        }

        @Override
        protected Void doInBackground(Void... voids) {
            SystemClock.sleep(1000);
            publishProgress("Toast msg string");
            SystemClock.sleep(1000);
            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            if (contextRef.get() != null) {
                Toast.makeText(contextRef.get(), values[0], Toast.LENGTH_SHORT).show();
            } else {
                // The context was destroyed.. check what you are doing
            }
        }
    }

这样使用

new ToastAsyncTask(MainActivity.this).execute();

我不会结束这个问题。我还没有解决我的问题,但是在其他情况下显然有效的答案数量表明还有其他事情正在发生。我将重新构造 类 以避开必须从 AsyncTask 中调用的问题。