我正在尝试从http请求中获取信息,但它显示以下错误:
> 06-17 18:06:05.931 10913-10913/com.example.user.project
> E/RecyclerView﹕ No adapter attached; skipping layout 06-17
> 18:06:05.947 10913-10913/com.example.user.project E/AndroidRuntime﹕
> FATAL EXCEPTION: main
> Process: com.example.user.project, PID: 10913
> android.os.NetworkOnMainThreadException
> at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
> at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
> at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
> at java.net.InetAddress.getAllByName(InetAddress.java:215)
> at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:142)
> at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
> at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
> at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
> at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
> at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
> at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
> at com.example.user.project.helper.JSONParser.makeHttpRequest(JSONParser.java:55)
> at com.example.user.project.itemActivity$getitem$1.run(itemActivity.java:120)
> at android.os.Handler.handleCallback(Handler.java:739)
> at android.os.Handler.dispatchMessage(Handler.java:95)
> at android.os.Looper.loop(Looper.java:135)
> at android.app.ActivityThread.main(ActivityThread.java:5254)
> at java.lang.reflect.description.invoke(Native description)
> at java.lang.reflect.description.invoke(description.java:372)
> at com.android.internal.os.ZygoteInit$descriptionAndArgsCaller.run(ZygoteInit.java:903)
> at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
itemActivity.java:
public class itemActivity extends AppCompatActivity {
private static final String TAG_SUCCESS = "success";
private static final String TAG_item = "item";
private static final String TAG_item_NAME = "name";
private static final String TAG_item_description = "description";
Integer item_id;
String name;
String username;
String description;
TextView itemname;
TextView itemdescription;
ProgressDialog pDialog;
JSONParser jParser;
RecyclerView recycler;
ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Intent i = getIntent();
if (i.hasExtra("item_id")) {
Bundle bd = getIntent().getExtras();
/*if ((!bd.getString("name").equals(null) || bd.getString("name").trim().length() > 0) && (!bd.getString("username").equals(null) || bd.getString("username").trim().length() > 0) && (!bd.getString("description").equals(null) || bd.getString("description").trim().length() > 0)) {
name = bd.getString("name");
username = bd.getString("username");
description = bd.getString("description");
}*/
item_id = bd.getInt("item_id");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
actionBar.setTitle(R.string.app_name);
itemname = (TextView) findViewById(R.id.itemName);
itemdescription = (TextView) findViewById(R.id.itemdescription);
new getitem().execute();
/*recycler = (RecyclerView) findViewById(R.id.recycler);
recycler.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(layoutManager);*/
}
/**
* Background Async Task to Get complete item details
*/
class getitem extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(itemActivity.this);
pDialog.setMessage(getResources().getString(R.string.loadingitem));
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting item details in background thread
*/
protected String doInBackground(String... params) {
// updating UI from Background Thread
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
myParameters.add(new BasicNameValuePair("item_id", Integer.toString(item_id)));
// getting item details by making HTTP request
// Note that item details url will use GET request
jParser = new JSONParser();
JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_item, "GET", myParameters);
// check your log for json response
Log.d("Single item Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received item details
JSONArray itemObj = json.getJSONArray(TAG_item); // JSON Array
// get first item object from JSON Array
JSONObject item = itemObj.getJSONObject(0);
// item with this pid found
// Edit Text
itemname.setText(item.getString(TAG_item_NAME));
itemdescription.setText(item.getString(TAG_item_description));
} else {
// item with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* *
*/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
/*itemname=(TextView)
findViewById(R.id.itemName);
itemdescription=(TextView)
findViewById(R.id.itemdescription);*/
//itemname.setText(name);
//itemdescription.setText(description);
activity_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="@bool/fitsSystemWindows">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height"
android:background="?colorPrimary" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height"
android:background="?colorPrimaryDark" />
</LinearLayout>
<FrameLayout
android:id="@+id/flma"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/status_bar_height">
<TextView
android:id="@+id/itemName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="80dp"
android:gravity="center"
android:textAllCaps="true"
android:textSize="25dp"
android:textStyle="bold" />
<ImageView
android:id="@+id/itemPhoto"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_gravity="center"
android:background="#000"
android:src="@drawable/header" />
<TextView
android:id="@+id/itemdescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="50dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="@bool/fitsSystemWindows"
app:headerLayout="@layout/navigation_drawer_header"
app:menu="@menu/navigation_drawer_menu"
app:theme="@style/NavigationViewTheme" />
</android.support.v4.widget.DrawerLayout>
JSONParser.java:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// función para obtener JSON desde la URL
public JSONObject makeHttpRequest(String url, String description, List<NameValuePair> params) {
try {
if(description == "POST"){
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(description == "GET"){
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
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 + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return jObj;
}
}
我正在尝试使用商品ID获取发送GET请求的商品的所有信息。查看错误,我认为在发出HTTP请求时失败是错误的,但我不确定。
有谁知道它失败的原因?
谢谢!
编辑:
现在我收到以下错误:
06-17 20:56:52.856 418-428/? E/art﹕ Failed sending reply to debugger: Broken pipe
06-17 20:57:07.391 418-767/com.example.user.project_test E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
Process: com.example.user.project_test, PID: 418
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:909)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4690)
at android.view.View.invalidateInternal(View.java:11801)
at android.view.View.invalidate(View.java:11765)
at android.view.View.invalidate(View.java:11749)
at android.widget.TextView.checkForRelayout(TextView.java:6858)
at android.widget.TextView.setText(TextView.java:4057)
at android.widget.TextView.setText(TextView.java:3915)
at android.widget.TextView.setText(TextView.java:3890)
at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:132)
at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:84)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
06-17 20:57:07.612 418-418/com.example.user.project_test E/WindowManager﹕ android.view.WindowLeaked: Activity com.example.user.project.itemActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{19feb64d V.E..... R......D 0,0-1026,348} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:298)
at com.example.user.project.itemActivity$getitem.onPreExecute(itemActivity.java:96)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
at android.os.AsyncTask.execute(AsyncTask.java:539)
at com.example.user.project.itemActivity.onCreate(itemActivity.java:71)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.description.invoke(Native description)
at java.lang.reflect.description.invoke(description.java:372)
at com.android.internal.os.ZygoteInit$descriptionAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
答案 0 :(得分:1)
它失败了,因为你试图在主线程android.os.NetworkOnMainThreadException
似乎是违规行是:
JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_RECIPE, "GET", params);
此调用失败的原因是因为您将其包装在runOnUIThread
调用中,该调用将尝试处理主线程上的所有内容。这反过来会导致您的网络请求(尽管处于异步任务中)在主线程上运行。
问题params
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
doInBackground
的参数称为params,您正在尝试创建另一个名为params
的变量。只需改变
List<NameValuePair> params = new ArrayList<NameValuePair>();
类似
List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
确保更新对params的所有引用。最好通过IDE中的重构工具来完成。
如此接近!这个错误也很容易解决。
默认情况下,doInBackground
在由AsyncTask生成和维护的后台线程中运行。因为这是后台线程而不是执行UI的主线程,所以不能在任何其他线程上对UI(edittext,标签,按钮等)进行更改,而是主要的。 此是我们要使用runOnUIThread
的地方。目前,在您的doInBackground
中,您有以下几行:
recipename.setText(recipe.getString(TAG_RECIPE_NAME));
recipemethod.setText(recipe.getString(TAG_RECIPE_METHOD));
将它们包装在runOnUIThread
runOnUIThread(new Runnable()
{
recipename.setText(recipe.getString(TAG_RECIPE_NAME));
recipemethod.setText(recipe.getString(TAG_RECIPE_METHOD));
});
但是,我建议您在此方法中返回字符串并在onPostExecute
中执行所有UI更改,因为默认情况下此方法在UI线程上运行。您也可以在onProgressUpdate
中进行更改,因为它将在UI线程上运行。