AsyncTask - 将postExecute中的String返回给Activity,它启动Async Task而不阻塞UI Thread

时间:2012-06-22 16:18:15

标签: android android-activity android-asynctask return

我有一个Activity,它使用Implemented进程对话框启动AsyncTask。这很好用!但是我希望在asyncTask完成时获得String返回。所以我必须在onPostExecute - Method中返回一些东西。 那个结果(字符串)我想抓住Activity,它启动了AsyncTask。 我不想使用.get(),因为它会阻止UI线程。

我必须写入onPostExecute并且Activity从doInBackground中获取字符串?

感谢您提供任何帮助以解决此问题;)

现在使用代码:

class BgDL extends AsyncTask<String, Integer, String> {

    String finishString="";
    private Context context;

    ProgressDialog pdialog;

    public BgDL(Context cxt) {  //get the context (usually "this" from Activity / otherwise progressdialog wont show up!
        context = cxt;
        pdialog = new ProgressDialog(context);

    }


    @Override
    protected String doInBackground(String... strings) {
        OutputStream output;
        ByteArrayOutputStream baos = null;

        try {
            URL url = new URL(strings[0]);
            URLConnection connection = url.openConnection();
            connection.connect();

            int fileLength = connection.getContentLength();

            InputStream input = new BufferedInputStream(url.openStream());
            if (strings[1]=="toString") { // write byte to string  if a file is not given
                baos= new ByteArrayOutputStream();
                output = new DataOutputStream(baos);
            } else { //otherwise to string
                output = new FileOutputStream(strings[1]);
            }
            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
       }
       output.flush();
       output.close();
       input.close();
       if (strings[1]=="toString") { 
           finishString = baos.toString(); //
       } // only write byte to string if a file is not given
    } catch (Exception e) {log.d("ex",e.toString());
    }
    return finishString;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pdialog.setTitle("Please wait");
        pdialog.setIndeterminate(false);
        pdialog.setMax(100);
        pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pdialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        pdialog.setProgress(progress[0]);

    }
    protected void onPostExecute(String...finishString) {
        pdialog.dismiss();//!!!!!!!!!finishString i want to pass over to my Activity, which started this asynctask with .execute();
    }

3 个答案:

答案 0 :(得分:2)

在项目中创建一个扩展活动的类,如下所示:

public class SomeClass extends Activity
{
    public void dataFromPostExecute(String data) 
    {
        System.out.println("in mainactivity");
    }
}

如果您想为每个活动创建一个单独的线程,只需创建一个扩展的类 Application

public class Async extends Application
{
private Socket globalSocket;

    @Override
    public void onCreate()
    {
        //socket = null;
    }

    public Socket getglobalSocket() 
    {
        return globalSocket;
    }

    public void setGlobalSocket(Socket globalSocket) 
    {
        this.globalSocket = globalSocket;
    }
}

在扩展Asynctask的套接字类中,执行以下操作:

public SocketClass extends AsyncTask<String,String,String>
{
    Async app;
    private SomeClass t_act;
    public SocketClass(SomeClass sct) 
    {
        t_act = sct;
        this.con = tst;
        app= ((Async)sct.getApplicationContext());
    }

    protected void onPostExecute(String data)
    {
        t_act.dataFromPostExecute(data);
    }
}

然后,在您的活动中扩展SomeClass并执行如下所示:

public class Activity1 extends SomeClass
{
    public void dataFromPostExecute(String data)
        {
            //do whatever you want. "data" of this method contains the values from                                     
              postexecute()
        }
}

答案 1 :(得分:1)

doInBackground()的返回值是onPostExecute()中的正式值。 所以你应该能够传入它。

答案 2 :(得分:1)

  

我有什么要写入onPostExecute并且Activity抓住了   来自doInBackground的字符串?

当您使用AsyncTask时,您只能使用UIonProgressUpdate方法更新onPostExecute

您的doInBackground()方法返回一些数据,这些数据将转到onPostExecute方法(这也取决于您的泛型的声明方式)。

一般来说,没有其他方法可以做到。

你的意思是:

AsyncTask a = new AsyncTask(Context);
a.execute(Input);

首先表示你的构造函数看起来像

public MyAsync(Context c) {
   this.c = c;
}

第二个意味着您将第一个泛型类型(假设输入参数为String)声明为

private class MyAsync extends AsyncTask<String, Void, String> {
  //...
}


您希望使用返回UI方法的String更新doInBackground(),并且仅使用onPostExecute参数放置IN方法{{ 1}}返回String

doInBackground()


因此,如果您想以不同的方式执行此操作,请更改您的应用程序逻辑,并使用protected void onPostExecute(String stringReturnedFromDoInBackground) { // some work } ResultReceiver一起使用。