【问题标题】:Android: how to wait AsyncTask to finish in MainThread?Android:如何在 MainThread 中等待 AsyncTask 完成?
【发布时间】:2012-10-26 01:33:39
【问题描述】:

我知道你首先要做的是......为什么你会使用 AsyncTask。

所以这是我的问题,我正在开发一些 Android 应用程序(Android 2.1 或更高版本的 API 7),我正在模拟器上进行测试,一切都很好,所以我在 HTC Sensation 上进行了测试,上面写着 NetworkOnMainThreadExeption!

我正在下载一些图片,然后在地图上绘制。

因此,在这种情况下,为了解决这个问题,每次(互联网连接)下载图片我都必须放在 AsyncTask 上才能工作。

所以我需要一种方法来知道所有图片何时完成,这样我就可以开始画画了..

我尝试了这么多,但没有结果我不知道。我有一个带有处理程序的解决方案,但如果在较慢的网络上运行,我会得到空指针(因为没有下载图片)。

所以请帮助我。

编辑:

这是一个想法:

Bitmap bubbleIcon ;
    onCreate(){
     ...
// i am making call for Async
new ImgDown().execute(url);
//and then i calling functions and classes to draw with that picture bubbleIcon !
DrawOnMap(bubbleIcon);
}




//THIS IS ASYNC AND FOR EX. SUPPOSE I NEED TO DOWNLOAD THE PIC FIRST
     class ImgDown extends AsyncTask<String, Void, Bitmap> {

        private String url;

        public ImgDown() {
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            url = params[0];
            try {
                return getBitmapFromURL(url);
            } catch (Exception err) {
            }

            return null;

        }

        @Override
        protected void onPostExecute(Bitmap result) {
            bubbleIcon = result;
            bubbleIcon = Bitmap
                    .createScaledBitmap(bubbleIcon, 70, 70, true);

        }

        public Bitmap getBitmapFromURL(String src) {
            try {
                Log.e("src", src);
                URL url = new URL(src);
                HttpURLConnection connection = (HttpURLConnection) url
                        .openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                // /tuka decode na slika vo pomalecuk kvalitet!
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 3;
                Bitmap myBitmap = BitmapFactory
                        .decodeStream(new FlushedInputStream(input));
                Log.e("Bitmap", "returned");
                return myBitmap;
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("getBitmapFromURL", e.getMessage());
                return null;
            }
        }

        class FlushedInputStream extends FilterInputStream {
            public FlushedInputStream(InputStream inputStream) {
                super(inputStream);
            }

            public long skip(long n) throws IOException {
                long totalBytesSkipped = 0L;
                while (totalBytesSkipped < n) {
                    long bytesSkipped = in.skip(n - totalBytesSkipped);
                    if (bytesSkipped == 0L) {
                        int byteValue = read();
                        if (byteValue < 0) {
                            break; // we reached EOF
                        } else {
                            bytesSkipped = 1; // we read one byte
                        }
                    }
                    totalBytesSkipped += bytesSkipped;
                }
                return totalBytesSkipped;
            }
        }
    }

我希望现在更清楚了。

【问题讨论】:

  • 请粘贴相关源码。如果您只提供非正式的描述,则无法提供帮助。
  • 我编辑了这篇文章。请看
  • 如果我使用进度对话框怎么办,请再次阅读我的问题...:/
  • 等待期间是否还有用户交互?如果没有,则使用进度对话框显示一个告诉用户等待的对话框
  • 所以你一直告诉我这行“DrawOnMap(bubbleIcon);”将在进度对话框结束后执行? ?

标签: android android-asynctask handler solution


【解决方案1】:
class OpenWorkTask extends AsyncTask {

    @Override
    protected Boolean doInBackground(String... params) {
        // do something
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // The results of the above method
        // Processing the results here
        myHandler.sendEmptyMessage(0);
    }

}

Handler myHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case 0:
            // calling to this function from other pleaces
            // The notice call method of doing things
            break;
        default:
            break;
        }
    }
};

【讨论】:

  • 你就是男人!非常感谢这就是我正在寻找的。非常感谢!你是最棒的
  • 是来自 Java.util 的吗?它没有要覆盖的handleMessage .. got、close()、flush() 和 publish(LogRecord 记录)
  • 发送广播并在适当的地方接收它是我认为更合适的解决方案。
【解决方案2】:

您可以使用 OOP 原则编写自己的 Delegate 来委托有关完成任务的信息:

task_delegate.java

public interface TaskDelegate {
    void TaskCompletionResult(String result);
}

ma​​in_activity.java

public class MainActivity extends Activity implements TaskDelegate {

    //call this method when you need     
    private void startAsynctask() {
      myAsyncTask = new MyAsyncTask(this);
      myAsyncTask.execute();
     }

//your code

    @Override
    public void TaskCompletionResult(String result) {
        GetSomethingByResult(result);
    }
}

my_asynctask.java

public class MyAsyncTask extends AsyncTask<Void, Integer, String> {

    private TaskDelegate delegate;

    protected MyAsyncTask(TaskDelegate delegate) {
        this.delegate = delegate;
    }

    //your code 

    @Override
    protected void onPostExecute(String result) {

        delegate.TaskCompletionResult(result);
    }
}

【讨论】:

    【解决方案3】:
    class openWorkTask extends AsyncTask<String, String, Boolean> {
    
        @Override
        protected Boolean doInBackground(String... params) {
            //do something
            return true;
        }
    
        @Override
        protected void onPostExecute(Boolean result) {
            // The results of the above method
            // Processing the results here
        }
    }
    

    【讨论】:

    • 我无法在那里处理结果,我有一些与其他请求不同的调用此函数的方法,所以.. 我需要一种方法来知道 AsyncTask 何时结束。
    • 网络数据获取完成时间可以发送HandlerMessage
    • 我该怎么做?你能给我举个例子吗?
    【解决方案4】:

    如果我是你,我会使用进度对话框。这样,用户可以在 ASyncTask 下载图片时看到正在发生的事情。在 PostExecute 上,从您的主代码中调用一个方法来检查图片是否为空。请记住,您无法在 doInBackground 方法中更新 UI,因此任何 UI 都可以在 onPreExecute 或 onPostExecute 中工作

    private class DownloadPictures extends AsyncTask<String, Void, String> 
    {
    
        ProgressDialog progressDialog;
    
        @Override
        protected String doInBackground(String... params) 
        {
    
            //Download your pictures
    
            return null;
    
        }
    
        @Override
        protected void onPostExecute(String result) 
        {
    
            progressDialog.cancel();
    
            //Call your method that checks if the pictures were downloaded
    
        }
    
        @Override
        protected void onPreExecute() {
    
            progressDialog = new ProgressDialog(
                    YourActivity.this);
            progressDialog.setMessage("Downloading...");
            progressDialog.setCancelable(false);
            progressDialog.show();
    
        }
    
        @Override
        protected void onProgressUpdate(Void... values) {
            // Do nothing
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多