0

Please help, as the code below that should send a GET request does not work.
Behaviour: after tapping the button it writes "Running", then uses some traffic, then after some time hangs and crashes.

My goal is to send HTTP GET and handle the response as a string. I have tried a lot of options but they failed.

I'll greatly appreciate any working way of HTTP requests that NOT run in the UI (main) thread. Requests in the main thread are no more allowed and throw a networkonmainthreadexception.

Thanks in advance!

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

<uses-permission android:name="android.permission.INTERNET" />

MainActivity.java (I'll delete waste imports later):

package com.aohdhgdsb.helloworld;

import android.app.DownloadManager;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ImageView;
import android.widget.Toast;
import android.os.Handler;
import android.widget.TextView.OnEditorActionListener;
import android.view.inputmethod.EditorInfo;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import android.os.AsyncTask;
import java.io.InputStream;
import java.net.URLConnection;


public class MainActivity extends AppCompatActivity {
    public EditText Edit1;
    public EditText Edit2;
    public TextView Text1;
    public ImageView Img1;
    public Button But1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        showToast("Hi. I have started!\r\nv6");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }






    public void showToast(String toast){
        try {
            Toast toast2 = Toast.makeText(getApplicationContext(),
                    "" + toast,
                    Toast.LENGTH_SHORT);
            //toast2.setGravity(Gravity.TOP, 0, 0);
            toast2.show();
        } catch (Throwable e) {
            showToast("Error while showing the toast!");
            /*
            Toast toast3 = Toast.makeText(getApplicationContext(),
                    "TOAST ERR: " + e,
                    Toast.LENGTH_LONG);
            toast3.show();
            */
        }
    }
    public String readStream(InputStream is) {
        try {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            int i = is.read();
            while(i != -1) {
                bo.write(i);
                i = is.read();
            }
            return bo.toString();
        } catch (IOException e) {
            return "";
        }
    }
    public void Go(View v) {
        handleResponse("Running...");
        Thread thread = new Thread(new Runnable(){
            @Override
            public void run() {
                //******************************************
                try{
                    URL url = new URL("http://example.com/");
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    try{
                        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                        handleResponse(readStream(in));
                    } catch (Throwable e) {showToast("ERROR7: " + e);}
                    finally {
                        urlConnection.disconnect();
                    }
                } catch (Throwable e) {
                    showToast("ERROR6: " + e);
                }
//****************************************
            }
        });

        thread.start();

    }

    public void handleResponse(String str){
        Edit2 = (EditText) findViewById(R.id.editText2);
        Edit2.setText(str);
    }
}

Part of activity_main.xml:

    <Button
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go!"
        android:id="@+id/button3"
        android:layout_gravity="center_horizontal"
        android:onClick="Go" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:id="@+id/editText2"
        android:layout_gravity="center_horizontal"
        android:layout_weight="8.25"
        android:text="Nothing" />
Mike
  • 1
  • Try with AsyncTask instead – Gueorgui Obregon Jan 26 '16 at 21:22
  • Please tell how to do that – Mike Jan 26 '16 at 21:26
  • 1
    [Using AsyncTask](http://stackoverflow.com/questions/18898039/using-asynctask/18898105#18898105) will get you started if you want to use that. But part of your problem here is that you are trying to show a Toast in a background Thread which will cause a problem. – codeMagic Jan 26 '16 at 21:28
  • here i made a simple sample http://stackoverflow.com/a/35023075/4848308 – Gueorgui Obregon Jan 26 '16 at 21:30
  • A more elegant approach would be using the Retrofit Library. Please take a look at the following link: http://blog.robinchutaux.com/blog/a-smart-way-to-use-retrofit/ – ap6491 Jan 26 '16 at 21:44

1 Answers1

0

Try using AsyncTask, simple example:

public class MyAsyncTask extends AsyncTask<String, Void, String> {
    Context context;

    //Constructor
    public AsyncWS(Context context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //BEFORE Execution
        //initialize a ProgressDialog, ...
    }


    @Override
    protected String doInBackground(String... args) {

        //MAke all the http calls

        return result; //This is going to be sent to onPostExecute
    }

    @Override
    protected void onPostExecute(String result) {
        //After Execution, here you are working again in the main thread
        super.onPostExecute(result);
        //Make toasts, change views, stop ProgressDialogs
    }

}

Call it with:

MyAsyncTask myAsyncTask = new MyAsyncTask (context);
myAsyncTask.execute(args); //args = String[]

Reference: http://developer.android.com/guide/components/processes-and-threads.html#WorkerThreads

Nikiole91
  • 344
  • 2
  • 10