简体   繁体   English

Android:如何在MainThread中等待AsyncTask完成?

[英]Android: how to wait AsyncTask to finish in MainThread?

I know that the first you gonna this is... why the heck on the world you then use AsyncTask. 我知道第一个你要这就是......为什么你会在世界上使用AsyncTask。

So here is my problem i am working on some Android app (API 7 for android 2.1 or higher) , and i am testing on emulator and everything was fine, so then i tested on HTC Sensation and it says NetworkOnMainThreadExeption! 所以这是我的问题我正在研究一些Android应用程序(API为Android 2.1或更高版本),我正在测试模拟器,一切都很好,所以然后我测试HTC Sensation,它说NetworkOnMainThreadExeption!

I was downloading some pictures and then draw on the map. 我正在下载一些图片,然后在地图上绘制。

So to solve this problem every (internet connection) in this case downloading the pictures i must put on AsyncTask to work. 所以要解决这个问题,每次(互联网连接)在这种情况下下载图片我必须把AsyncTask放到工作。

So i need a method how to know when all pictures are done so i can start drawing.. 所以我需要一种方法如何知道所有图片何时完成所以我可以开始绘图..

I was trying so much and no result i have no idea. 我试了这么多,没有结果我不知道。 I got one solution with handler but if run on slower net i get nullpointer(because the pictures are not downloaded). 我有一个处理程序的解决方案,但如果在较慢的网络上运行我得到nullpointer(因为图片没有下载)。

So please help me. 所以请帮助我。

EDIT: 编辑:

here is the idea: 这是一个想法:

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;
            }
        }
    }

i hope now is more clear. 我希望现在更清楚了。

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;
        }
    }
};

You can write your own Delegate to delegate info about finishing the task, using OOP principles: 您可以使用OOP原则编写自己的委托来委派有关完成任务的信息:

task_delegate.java task_delegate.java

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

main_activity.java main_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 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);
    }
}
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
    }
}

I would use a Progress Dialog if I were you. 如果我是你,我会使用进度对话。 This way users can see that something is happening while the ASyncTask downloads the picture. 这样,用户可以在ASyncTask下载图片时看到正在发生的事情。 On PostExecute, call a method from your main code that checks if the pictures are null. 在PostExecute上,从主代码中调用一个方法来检查图片是否为空。 Remember you cannot update the UI in the doInBackground method so do any UI work in either onPreExecute or onPostExecute 请记住,您无法在doInBackground方法中更新UI,因此请在onPreExecute或onPostExecute中执行任何UI工作

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
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM