如何将数据从AsyncTask返回到主线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将数据从AsyncTask返回到主线程相关的知识,希望对你有一定的参考价值。
我想将Jsonobject返回到主线程。但是,当我尝试运行代码时,它返回以下错误。
02-06 06:14:36.490: E/androidRuntime(769): FATAL EXCEPTION: main
02-06 06:14:36.490: E/AndroidRuntime(769): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dataread/com.example.dataread.MainActivity}: java.lang.NullPointerException
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.os.Handler.dispatchMessage(Handler.java:99)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.os.Looper.loop(Looper.java:137)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread.main(ActivityThread.java:5039)
02-06 06:14:36.490: E/AndroidRuntime(769): at java.lang.reflect.Method.invokeNative(Native Method)
02-06 06:14:36.490: E/AndroidRuntime(769): at java.lang.reflect.Method.invoke(Method.java:511)
02-06 06:14:36.490: E/AndroidRuntime(769): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-06 06:14:36.490: E/AndroidRuntime(769): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-06 06:14:36.490: E/AndroidRuntime(769): at dalvik.system.NativeStart.main(Native Method)
02-06 06:14:36.490: E/AndroidRuntime(769): Caused by: java.lang.NullPointerException
02-06 06:14:36.490: E/AndroidRuntime(769): at com.example.dataread.MainActivity.onCreate(MainActivity.java:37)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.Activity.performCreate(Activity.java:5104)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-06 06:14:36.490: E/AndroidRuntime(769): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-06 06:14:36.490: E/AndroidRuntime(769): ... 11 more
这是我的代码:
public interface Asynchtask
{
void processFinish(JSONObject result);
}
public class MainActivity extends ListActivity implements Asynchtask
{
JSONfunctions js= new JSONfunctions();
JSONObject retunfromAsyncTask;
//public static JSONObject dataFromAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
js.delegate = this;
new JSONfunctions().execute("http://192.168.6.43/employees.php");
setContentView(R.layout.listplaceholder);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
try {
JSONArray employees = retunfromAsyncTask.getJSONArray("Employees");
for(int i=0;i<employees.length();i++){
JSONArray e = employees.getJSONArray(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", "emp name:" + e.getString(0)+" "+e.getString(1)+" "+e.getString(2));
map.put("email id", "email id: " + e.getString(3));
map.put("phone no", "phone no: " + e.getString(4));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.activity_main,
new String[] { "name", "email id","phone no" },
new int[] { R.id.item_title, R.id.item_emailid ,R.id.item_phoneno});
setListAdapter(adapter);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
}
@Override
public void processFinish(JSONObject result) {
// TODO Auto-generated method stub
retunfromAsyncTask=result;
}
}
public class JSONfunctions extends AsyncTask<String, Void, JSONObject> {
public Asynchtask delegate=null;
InputStream is;
String result ;
JSONObject jArray;
@Override
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "
");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
// MainActivity.dataFromAsyncTask=jArray;
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
//convert response to string
}
@Override
protected void onPostExecute(JSONObject result)
{
delegate.processFinish(result);
}
}
manifest资源配置文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dataread"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.dataread.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案
要在Main Thread中获得结果,您将需要使用AsyncTask.get()方法,该方法使UI线程等待,直到doInBackground
的执行未完成,但get()方法调用冻结主UI线程,直到doInBackground
计算未完成。使用get()方法启动你的AsyncTask
:
String str_result=new
JSONfunctions().execute("http://192.168.6.43/employees.php").get();
在Thread中移动此行以避免冻结UI线程
Second and right way to utilize the use of
AsyncTask
move your code which you want to update with the result of doInBackground
computation inside onPostExecute as :
public class JSONfunctions extends
AsyncTask<String, Void, JSONObject> {
public Asynchtask delegate=null;
InputStream is;
String result ;
JSONObject jArray;
@Override
protected JSONObject doInBackground(String... params) {
// your code here....
return jArray;
//convert response to string
}
@Override
protected void onPostExecute(JSONObject result)
{
JSONArray employees =
result.getJSONArray("Employees");
// your code here...
ListAdapter adapter = new SimpleAdapter(MainActivity.this, mylist ,
R.layout.activity_main,
new String[] { "name", "email id","phone no" },
new int[] { R.id.item_title, R.id.item_emailid
,R.id.item_phoneno});
MainActivity.this.setListAdapter(adapter);
final ListView lv = MainActivity.this.getListView();
//....
}
}
另一答案
new JSONfunctions().execute("http://192.168.6.43/employees.php");
但我在哪里设置它的代表?
public Asynchtask delegate=null;
所以我认为你在这里获得NPE:
delegate.processFinish(result);
附:这一行js.delegate = this;与新的JSONfunctions实例无关。它为另一个实例设置委托(JSONfunctions js = new JSONfunctions();)
另一答案
使用get()我们可以从Async获得结果
response=new NetworkCallsHandler(this).execute(NetworkConstants.ASSETEVENTREPORT).get();
以上是关于如何将数据从AsyncTask返回到主线程的主要内容,如果未能解决你的问题,请参考以下文章