1

我有一个 Activity,它启动一个带有已实现进程对话框的 AsyncTask。这很好用!但是我想在 asyncTask 完成后得到一个字符串返回。所以我必须在 onPostExecute - 方法中返回一些东西。我想在启动 AsyncTask 的 Activity 中获取该结果(字符串)。我不想使用 .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();
    }
4

3 回答 3

2

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

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

如果您希望每个活动都有一个线程,只需创建一个扩展 应用程序的类

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()
        }
}
于 2013-02-13T05:45:13.150 回答
1

我必须在 onPostExecute 中写入什么,而 Activity 从 doInBackground 中获取字符串?

当您使用时AsyncTask,您可以更新您UI唯一的 ononProgressUpdateonPostExecute方法。

您的doInBackground()方法返回一些数据,这些数据将传递给onPostExecute方法(这也取决于您的泛型是如何声明的)。

通常,没有其他方法可以做到这一点。

你的意思是:

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

首先意味着您的构造函数看起来像

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

第二意味着您将第一个泛型类型(假设 Input param is String)声明为

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


并且您想UI使用String该返回doInBackground()方法进行更新,而只需放置带有返回参数的onPostExecute方法。INStringdoInBackground()

protected void onPostExecute(String stringReturnedFromDoInBackground) 
{
   // some work
}


因此,如果您想以不同的方式执行此操作,请更改您的应用程序逻辑并使用ResultReceiver例如IntentService.

于 2012-06-22T16:47:59.617 回答
1

doInBackground() 的返回值在 onPostExecute() 中是正式的。因此,您应该能够将其传递进去。

于 2012-06-22T16:22:01.650 回答