[英]Android JSON Parsing Crashing Application AsyncTask
我正在使用JSON解析器從JSON文件讀取數據並將其顯示在我的應用程序中,我最初是使用此代碼來創建可以正常工作的數組,但現在我將其粘貼到新的應用程序中以使其從JSON並將其放在無法正常工作的文本字段中。 我將在下面發布代碼和錯誤日志。
package com.example.curtisboylan.myapplication;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TechnicianProfile extends AppCompatActivity {
private static String url;
private String TAG = SearchScreen.class.getSimpleName();
private ProgressDialog pDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_technician_profile);
Bundle bundle = getIntent().getExtras();
String username = bundle.getString("username");
String userid = bundle.getString("userid");
setTitle("Technician - " + username);
url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;
Log.d("test", url);
new GetProfile().execute();
}
private class GetProfile extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(TechnicianProfile.this);
pDialog.setMessage("Please Wait..");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("MyGeek");
TextView usernametext;
// looping through All Contacts
JSONObject c = contacts.getJSONObject(0);
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
usernametext.setText(c.getString("name"));
// username.add(c.getString("name"));
// userid.add(c.getString("id"));
// location.add(c.getString("location"));
// reviewscore.add(c.getString("reviewscore"));
// price.add(c.getString("price"));
// urllist.add(c.getString("url"));
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
}
D /測試: http ://curtisboylan.me/mygeek/mygeekprofile.php?user=1 E / EGL_emulation:tid 2593:eglSurfaceAttrib(1174):error 0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:無法在表面0x91199f00上設置EGL_SWAP_BEHAVIOR錯誤= EGL_BAD_MATCH E / EGL_仿真:tid 2593:eglSurfaceAttrib(1174):錯誤0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:無法在表面0x8f2f5000上設置EGL_SWAP_BEHAVIOR,錯誤= EGL_BAD_MATCH {我從“:” “ id”:“ 1”,“ name”:“ Curtis Boylan”,“ location”:“ Swords,Co Dublin”,“ reviewscore”:“ 5.6”,“ url”:“ https:// scontent-lhr3-1 .xx.fbcdn.net / v / t1.0-9 / 11062691_831452480236559_1123476984274233173_n.jpg?oh = 8eb4bb9519a2cd3b96b085146b0ae718&oe = 596BBB5F“,”價格“:” 30“}]}
--------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2 Process: com.example.curtisboylan.myapplication, PID: 2416 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:325) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
創建視圖層次結構的原始線程可以觸摸其視圖。 在android.view.ViewGroup.invalidateChild(ViewGroup.java:5205)在android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083)在android.view.ViewRootImpl.checkThread(ViewRootImpl.java:1083)處。 android.view.View.invalidate(View.java:13620)的android.view.View.invalidate(View.java:13604)的android.widget.TextView.checkForRelayout(TextView的View.invalidateInternal(View.java:13656) .java:7347),位於android.widget.TextView.setText(TextView.java:4480),位於android.widget.TextView.setText(TextView.java:4337),位於android.widget.TextView.setText(TextView.java:4312)在com.example.curtisboylan.myapplication.TechnicianProfile $ GetProfile.doInBackground(TechnicianProfile.java:72)處com.example.curtisboylanlan.myapplication.TechnicianProfile $ GetProfile.doInBackground(TechnicianProfile.java:39)在android.os.AsyncTask $ 2處。在java.util.concurrent.FutureTask.run(FutureTask.java:237)處調用android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:243)處的調用(AsyncTask.java:305)。 util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:607)at java.lang.Thread.run(Thread.java:761)E / EGL_Emulation:tid 2593:eglSurfaceAttrib(1174):錯誤0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:無法在表面0x8f2f5080上設置EGL_SWAP_BEHAVIOR,錯誤= EGL_BAD_MATCH E / WindowManager:android.view.Window。泄漏了DecorView @ 415df5e []窗口,該窗口最初是在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)的android.view.ViewRootImpl。(ViewRootImpl.java:418)此處添加的,而在android.view.WindowManagerImpl.addView (WindowManagerImpl.java:93),位於android.app.Dialog.show(Dialog.java:322),位於com.example.curtisboylan.myapplication.TechnicianProfile $ GetProfile.onPreExecute(TechnicianProfile.java:48),位於android.os.AsyncTask。 android.os.AsyncTask.execute(A上的executeOnExecutor(AsyncTask.java:620) com.example.curtisboylan.myapplication.TechnicianProfile.onCreate(TechnicianProfile.java:36)上的syncTask.java:567)android.app.Instrumentation.callActivityOnCreate(Instrumentation)上的android.app.Activity.performCreate(Activity.java:6679) .java:1118,位於android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618),位於android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726),位於android.app.ActivityThread.-wrap12(ActivityThread.java),位於android.os.Looper.loop(Looper.java:154)處的android.os.Handler.dispatchMessage(Handler.java:102)處的android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1477) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886)的java.lang.reflect.Method.invoke(本機方法)的.ActivityThread.main(ActivityThread.java:6119) .internal.os.ZygoteInit.main(ZygoteInit.java:776)E / WindowManager:android.view.WindowLeaked:活動com.example.curtisboylan.myapplication.TechnicianLis tView泄漏了DecorView @ b6a1d55 []窗口,該窗口最初在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)的android.view.ViewRootImpl。(ViewRootImpl.java:418)此處添加。 android.app.Dialog.show(Dialog.java:322)上com.example.curtisboylan.myapplication.TechnicianListView $ GetContacts.onPreExecute(TechnicianListView.java:78)上的android.os.AsyncTask上的addView(WindowManagerImpl.java:93) com.example.curtisboylan.myapplication.TechnicianListView.initViews(TechnicianListView.java:67)上android.os.AsyncTask.execute(AsyncTask.java:567)上的.executeOnExecutor(AsyncTask.java:620)。 android.app.Activity.performCreate(Activity.java:6679)處的myapplication.TechnicianListView.onCreate(TechnicianListView.java:48)android.app.ActivityThread.performLaunchActivity處的android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) (ActivityThread.java:2618)在android.app.ActivityThread.handleLaunchAct 在android.app.ActivityThread.-wrap12(ActivityThread.java)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1477)在android.os.Handler.dispatchMessage(Handler)的ivity(ActivityThread.java:2726) com的java.lang.reflect.Method.invoke(本機方法)處的android.os.Looper.loop(Looper.java:154)處的android.os.Looper.loop(Looper.java:154) .android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886)在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
您不能在doInBackground
執行任何UI操作。
將與設置文本相關的內容放入AsyncTask
onPostExecute
方法中
@Override
protected void onPostExecute(Void aVoid) {
}
從doInBackground中刪除UI組件,並在Asynctask的postExecute方法中更新UI
您正在嘗試從后台線程修改視圖。
以非線程安全的方式查看Android UI,因此只能從主線程進行修改。
冒犯的是您doInBackground()
這一行
usernametext.setText(c.getString("name"));
相反,您應該從doInBackground
返回找到的String,重寫onPostExecute
並將其設置在那里。
另一個選擇是將換行包裝在runOnUiThread()
但老實說,在這種情況下,它更復雜且不必要。
你不能使用
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
usernametext.setText(c.getString("name"));
從.doInbackground()方法開始,因為此方法在后台線程上執行,但是UI元素只能從主線程更改。 將UI更新移至.onPostExecute()方法。
由於錯誤提示“由android.view.ViewRootImpl $ CalledFromWrongThreadException引起”,您在錯誤的線程中執行了錯誤的操作。 請將您的setText
代碼移至onPostExecute
。
您必須使用publishProgress
和onProgressUpdate
。
package com.example.curtisboylan.myapplication;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TechnicianProfile extends AppCompatActivity {
private static String url;
private String TAG = SearchScreen.class.getSimpleName();
private ProgressDialog pDialog;
private TextView usernametext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_technician_profile);
usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
Bundle bundle = getIntent().getExtras();
String username = bundle.getString("username");
String userid = bundle.getString("userid");
setTitle("Technician - " + username);
url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;
Log.d("test", url);
new GetProfile(usernametext).execute();
}
private class GetProfile extends AsyncTask<Void, String, Void> {
private TextView tv;
public GetProfile(TextView tv) {
this.tv = tv;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(TechnicianProfile.this);
pDialog.setMessage("Please Wait..");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("MyGeek");
// looping through All Contacts
JSONObject c = contacts.getJSONObject(0);
String str = c.getString("name");
publishProgress(str);
// username.add(c.getString("name"));
// userid.add(c.getString("id"));
// location.add(c.getString("location"));
// reviewscore.add(c.getString("reviewscore"));
// price.add(c.getString("price"));
// urllist.add(c.getString("url"));
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
tv.setText(values[0]);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.