alexca
alexca

Reputation: 549

Android fails when trying to GET http request

I'm trying to get information from a http request but it shows the following error:

> 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;

    }
}

I'm trying to get all the information of a item sending a GET request with the item ID. Viewing mistake, I think the failure is something wrong when I make the HTTP request but I'm not sure.

Does anyone know why it fails?

Thank you!

EDIT:

Now I'm getting the following error:

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)

Upvotes: 0

Views: 1269

Answers (1)

d0nut
d0nut

Reputation: 2834

It's failing because you're trying to get the recipe on the main thread android.os.NetworkOnMainThreadException

What seems to be the offending line is this:

JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_RECIPE, "GET", params);

The reason why this call will fail is because you wrapped it in a runOnUIThread call which will try to process everything on the main thread. This in turn causes your network request, despite being in an async task, to run on the main thread.


Issue with 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>();

The paramater for doInBackground is called params and you're trying to make another variable called params. Just change

List<NameValuePair> params = new ArrayList<NameValuePair>();

to something like

List<NameValuePair> myParameters = new ArrayList<NameValuePair>();

Make sure to update all references to params as well. This is best done through the refactoring tool in your IDE.


So close! This error is also really easy to fix.

By default doInBackground runs in a background thread spawned and maintained by AsyncTask. Because this is a background thread and not the main thread where UI is performed you cannot make changes to the UI (edittext, labels, buttons, etc) on any other thread but main. This is where we want to use runOnUIThread. Currently, in your doInBackground you have the following lines:

recipename.setText(recipe.getString(TAG_RECIPE_NAME));
recipemethod.setText(recipe.getString(TAG_RECIPE_METHOD));

Just wrap them in runOnUIThread

runOnUIThread(new Runnable()
{
    recipename.setText(recipe.getString(TAG_RECIPE_NAME));
    recipemethod.setText(recipe.getString(TAG_RECIPE_METHOD));
});

However, I would suggest that you return the strings in this method and perform all UI changes in onPostExecute as this method runs on the UI Thread by default. You can also make changes in onProgressUpdate since that will run on the UI thread.

Upvotes: 1

Related Questions