Android:如何将AsyncTask的结果传递给主线程?

时间:2012-06-12 08:04:11

标签: android multithreading asynchronous

我有一个实现AsyncTask的类。

它计算一个对象(User),我想将该对象返回到主(UI)线程以传递给新活动。

我知道它是用 Activity.runOnUiThread()完成的,但是我无法理解传递给这个函数的内容等等? (我想在主线程中设置变量 User usr = value

我该怎么办?

谢谢

修改: 使用“Vipul Shah”代码我得到“未接受的关闭”。 这是日志(来自logcat):

06-12 10:28:05.404: E/AndroidRuntime(1475): FATAL EXCEPTION: AsyncTask #1
06-12 10:28:05.404: E/AndroidRuntime(1475): java.lang.RuntimeException: An error occured while executing doInBackground()
06-12 10:28:05.404: E/AndroidRuntime(1475):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.lang.Thread.run(Thread.java:856)
06-12 10:28:05.404: E/AndroidRuntime(1475): Caused by: java.lang.NullPointerException
06-12 10:28:05.404: E/AndroidRuntime(1475):     at org.ksoap2.serialization.SoapSerializationEnvelope.getResponse(SoapSerializationEnvelope.java:513)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at es.es.ValidacionThread.doInBackground(ValidacionThread.java:65)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at es.es.ValidacionThread.doInBackground(ValidacionThread.java:1)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
06-12 10:28:05.404: E/AndroidRuntime(1475):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-12 10:28:05.404: E/AndroidRuntime(1475):     ... 4 more

ValidacionTask完整源代码:

package es.es;

import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;



public class ValidacionThread extends AsyncTask<String, Object, Usuario> {

    private final String NAMESPACE = "http://webservices.pcp/";
    private final String URL = "http://127.0.0.1:8080/webServices/pcpWS?wsdl";
    private final String SOAPACTION = "";
    private final String METHOD = "ValidarUsuario";
    private AccesoCuentaActivity act;

    //Handler handler;

    private Context context;

    public ValidacionThread(Context context){
        this.context = context;
    }

    protected Usuario doInBackground(String[] pars) {

                 String user = pars[0];
                 String password = pars[1];
                SoapObject request = new SoapObject(NAMESPACE, METHOD); 
                SoapSerializationEnvelope sobre = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                sobre.dotNet = false;       
                request.addProperty("login", user);        
                request.addProperty("password", password); 
                sobre.setOutputSoapObject(request); 

                HttpTransportSE transporte = new HttpTransportSE(URL);        
                try {
                    transporte.call(SOAPACTION, sobre);
                } catch (IOException e) {
                //  JOptionPane.e.printStackTrace();
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (XmlPullParserException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                SoapObject resultado = null;
                try {
                    resultado = (SoapObject)sobre.getResponse();
                } catch (SoapFault e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                Usuario usu = new Usuario();
                usu.IdUsuario= resultado.getProperty(0).toString();
                usu.Nombre = resultado.getProperty(1).toString();
                usu.Apellidos = resultado.getProperty(2).toString();
                usu.Rol = resultado.getProperty(3).toString();   
                usu.Centro=resultado.getProperty(4).toString();
                return usu;     

}
       protected void onPostExecute(Usuario usu) {
          Intent intent = new Intent(context, MainActivity.class);
           intent.putExtra("result", usu);
           context.startActivity(intent);
           super.onPostExecute(usu);

        }

       protected void onProgress(Usuario usu) {

        }

}

3 个答案:

答案 0 :(得分:2)

我希望您了解onPostExecute和onProgressUpdate,它们为我们提供了UI线程工作..

如果仍然希望你的活动在AsyncTask中然后可以在构造函数中传递它我不确定这种做法是如何好的并且有任何长期问题,但一般工作正常........

public class MyAsyncTaskextends AsyncTask<String, Void, String> {
private <YOUR>Activity mActivity;

 public MyAsyncTaskextends (<YOUR>Activity activity){
          super();
         mActivity = activity;
}

答案 1 :(得分:2)

  

它计算一个对象(User),我想将该对象返回给main   (UI)要传递给新活动的威胁。

对象的计算应该在doInBackground方法中进行,并且一旦完成,使用onPostExceute方法来执行UI部分。

以下代码段将为您提供帮助。

示例活动类。

    public class HelloActivity extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new MyTask(this).execute("");
    }


}

<强> MyTask.java

class MyTask extends AsyncTask<String, Object, String> {

        private Context context;

        public MyTask(Context context) {
            this.context = context;
        }

        @Override
        protected String doInBackground(String... params) {
            // Do background operations here and once done return the result.

            return result;
        }

        @Override
        protected void onPostExecute(String result) {

            // Here you will receive that result.

            Intent intent = new Intent(context, SecondActivity.class);
            intent.putExtra("result", result);
            context.startActivity(intent);
            super.onPostExecute(result);
        }

    }

答案 2 :(得分:1)

最好的方法是使用Handle对象。

final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
      User user = (User) msg.obj;
    // here is your code 
      }
};

在你的帖子中

msg = handler.obtainMessage();
msg.obj = user;
handler.sendMessage(msg);

不要忘记在Tasks构造函数

中提供指向处理程序的链接