how to call UI or UI thread in doInBackground method

943 views Asked by At

I'm using AsyncTask class to connect with database. Based on data I will create dynamic EditText, Checkbox without involving XML file.

lView = new LinearLayout(this); - Here I'm facing with error!

enter image description here

Is there any way to call UI thread inside of doInBackground method!

Thanks in advance!!

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

    HashMap<String, bean> map = new HashMap<String, bean>();

    try {
        url = new URL("http://localhost/app/alldata.php");
    } catch (MalformedURLException e) {
        Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
        e.printStackTrace();
        return null;
    }

    try {
        conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(READ_TIMEOUT);
        conn.setConnectTimeout(CONNECTION_TIMEOUT);
        conn.setRequestMethod("POST");

        // setDoInput and setDoOutput method depict handling of both send and receive
        conn.setDoInput(true);
        conn.setDoOutput(true);

        // Append parameters to URL
        Uri.Builder builder = new Uri.Builder()
                .appendQueryParameter("user_id", "user_id")
                .appendQueryParameter("dpt_id","dptid");
        String query = builder.build().getEncodedQuery();

        // Open connection for sending data
        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
        writer.write(query);
        writer.flush();
        writer.close();
        os.close();
        conn.connect();

    } catch (IOException e1) {
        e1.printStackTrace();
    }

    try {
        int response_code = conn.getResponseCode();
        lView = new LinearLayout(this);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    } finally {
        conn.disconnect();
    }

    return null;
}
3

There are 3 answers

0
JoKr On

You can call publishProgress() from doInBackground method and override onProgressUpdate which will be called on UI thread.

Obviously, this is intented for progress-like usage. You should have clearly separated one unit of work for background and then process it normally in onPostExecute.

0
JuLes On

If you really want to communicate with the main UI Thread you can use:

runOnUiThread(new Runnable() {
        @Override
        public void run() {
         //place your code here
     }
});
0
Reaz Murshed On

The more elegant way of doing this is passing a callback function so that when your AsyncTask finishes its job, it can invoke the method call in your Activity and then you can make necessary changes there.

I would like to suggest keeping an interface like this.

public interface HttpResponseListener {
    void httpResponseReceiver(String result);
}

Now, in your Activity, you need to implement this listener and when executing your AsyncTask you need to pass the listener to that AsyncTask too.

public YourActivity extends Activity implements HttpResponseListener {

    // ... Other functions

    @Override
    public void httpResponseReceiver(String result) {
        int response_code = (int) Integer.parseInt(result);

        // Take necessary actions here
        lView = new LinearLayout(this);
    }
}

Now in your AsyncTask you need to have a variable first as a listener to your Activity.

public class HttpRequestAsyncTask extends AsyncTask<Void, Void, String> {

    // Declare the listener here 
    public HttpResponseListener mHttpResponseListener;

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

        HashMap<String, bean> map = new HashMap<String, bean>();

        try {
            url = new URL("http://localhost/app/alldata.php");
        } catch (MalformedURLException e) {
            Toast.makeText(getApplicationContext(), "URL Exception", Toast.LENGTH_LONG).show();
            e.printStackTrace();
            return null;
        }

        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(READ_TIMEOUT);
            conn.setConnectTimeout(CONNECTION_TIMEOUT);
            conn.setRequestMethod("POST");

            // setDoInput and setDoOutput method depict handling of both send and receive
            conn.setDoInput(true);
            conn.setDoOutput(true);

            // Append parameters to URL
            Uri.Builder builder = new Uri.Builder()
                    .appendQueryParameter("user_id", "user_id")
                    .appendQueryParameter("dpt_id","dptid");
            String query = builder.build().getEncodedQuery();

            // Open connection for sending data
            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            writer.write(query);
            writer.flush();
            writer.close();
            os.close();
            conn.connect();

        } catch (IOException e1) {
            e1.printStackTrace();
        }

        try {
            // int response_code = conn.getResponseCode();  // Return the result to onPostExecute
            // lView = new LinearLayout(this); // Remove this from here
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }

        return conn.getResponseCode() + "";
    }

    // Set the result here
    @Override
    protected void onPostExecute(final String result) {
        mHttpResponseListener.httpResponseReceiver(result);
    }
}

Now from your Activity, when you're starting the AsyncTask you need to assign the listener first like this.

HttpRequestAsyncTask mHttpRequestAsyncTask = new HttpRequestAsyncTask();
mHttpRequestAsyncTask.mHttpResponseListener = YourActivity.this;

// Start your AsyncTask
mHttpRequestAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Hope that helps!