This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 7 years ago.
I am working on an android application which connect with an asp.net web service.. for that when I tested the application is showing response
Android OS on network main thread exception".
My Code
class GetDetails extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading the result... Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
try
{
runOnUiThread(new Runnable() {
#Override
public void run()
{
TextView webserviceResponse = (TextView) findViewById(R.id.textView1);
webserviceResponse.setText("Requesting to server .....");
//Create Webservice class object
WebserviceCall com = new WebserviceCall();
// Initialize variables
String weight = "18000";
String fromUnit = "Grams";
String toUnit = "Kilograms";
//Call Webservice class method and pass values and get response
String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit);
//Alert message to show webservice response
Toast.makeText(getApplicationContext(), weight+" Gram= "+aResponse+" Kilograms",
Toast.LENGTH_LONG).show();
Log.i("AndroidExampleOutput", "----"+aResponse);
webserviceResponse.setText("Response : "+aResponse);
}
}
);
}
finally {
}
return null;
}
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
Move your all code from runOnUiThread(new Runnable() {...} to doInBackground(...)
As runOnUiThread(..) code execute in main thread
also initialized your Views in Activity onCreate(..)
Correct:
class GetDetails extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading the result... Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
try
{
webserviceResponse.setText("Requesting to server .....");
//Create Webservice class object
WebserviceCall com = new WebserviceCall();
// Initialize variables
String weight = "18000";
String fromUnit = "Grams";
String toUnit = "Kilograms";
//Call Webservice class method and pass values and get response
String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit);
Log.i("AndroidExampleOutput", "----"+aResponse);
return aResponse;
}
}
return null;
}
}
protected void onPostExecute(String aResponse) {
// dismiss the dialog once got all details
pDialog.dismiss();
//Alert message to show webservice response
Toast.makeText(getApplicationContext(), weight+" Gram= "+aResponse+" Kilograms",
Toast.LENGTH_LONG).show();
webserviceResponse.setText("Response : "+aResponse);
}
}
Hi Use Handler to Update UI.
Handler Example
private Handler handler = new Handler(new Handler.Callback() { #Override public boolean handleMessage(Message msg) {
switch( msg.what ){
case MSG:
progressDialog.show();
break;
case DETACH:
progressDialog.dismiss();
break;
}
return false; } });
Call In Do In Background
Message m=Message.obtain();
prepareMessage(m);
handler.sendMessage(m);
public void prepareMessage(Message m)
{
Bundle b = new Bundle();
b.putString("message", "Activity Done in background!!!!!!!");
m.setData(b);
}
Inside doInBackground() you have written a runonUiThread() method.
And inside that runOnUIThread() you are trying to make network call.That is why it is giving NetworkOnMainThreadException.
Put that network call outside runOnUiThread() String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit); but inside doInBackground() I hope it ll work.
Related
i'm developing an android App.
The user registration process calls a service that sends an email so it takes several seconds, like 5 or 6 seconds,that's why I execute that task within a thread. The problem is, the Dialog is never dismissing. It stays rolling and the user can do nothing. Here's my code:
try
{
final ProgressDialog progDailog = new ProgressDialog(ActividadAltaUsuario.this);
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
URL url = new URL("slowWS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = IOUtils.toString(in, "UTF-8");
final JSONObject jsonPrincipal = new JSONObject(response);
Boolean success = jsonPrincipal.get("status").toString() == "true";
if (success)
{
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.show(ActividadAltaUsuario.this, "Sendind email");
}
});
final String idUsuario = jsonPrincipal.get("idUsuario").toString();
URL url2 = new URL("anotherSlowWS");
HttpURLConnection conn2 = (HttpURLConnection) url2.openConnection();
conn2.setRequestMethod("POST");
InputStream in2 = new BufferedInputStream(conn2.getInputStream());
String response2 = IOUtils.toString(in2, "UTF-8");
JSONObject jsonRtaMail = new JSONObject(response2);
//finish();
}
else
{
//finish();
showToast(jsonPrincipal.get("message").toString());
}
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.dismiss();
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
catch(Exception e)
{
Log.e("log_tag", "Error in http connection" + e.toString());
}
Can anybody help me?
Thanks!
AsyncTask would be a better approach instead of thread, Replace your network call from thread to use AsyncTask. You can use something like this
private class LongOperation extends AsyncTask<Void, Void, Void> {
#Override
protected String doInBackground(Void... params) {
//Main stuff that needs to be done in background
}
#Override
protected void onPostExecute(Void result) {
//Post Execution this method will be called, handle result accordingly
//You can dismiss your dialog here
}
#Override
protected void onPreExecute() {
//Do initialization relative stuff here
// Initialize your dialog here.
}
}
As both onPostExecute() and onPreExecute() work on main thread you can show and dismiss your dialog in this methods.
The UI controls have to be accessed only from the UI thread.
Usually I do this in class that extends AsyncTask
Something like:
public class MyTask extends AsyncTask {
protected void onPreExecute() {
//create and display your alert here
progDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Logging ...", true);
}
protected Void doInBackground(Void... unused) {
// here is the thread's work ( what is on your method run()
...
// if we want to show some progress in UI, then call
publishProgress(item)
}
protected void onProgressUpdate(Item... item) {
// theoretically you can show the progress here
}
protected void onPostExecute(Void unused) {
//dismiss dialog here where the thread has finished his work
progDialog.dismiss();
}
}
LE:
More detalis about AsyncTask https://developer.android.com/reference/android/os/AsyncTask
check especially the Protected Methods
I am new to android development.I have done some android application to cummounicate with webservice and get data from it into local database in android device.I used AsyncTask<,,> Method to transfer data from internet.
Then I used ProgressDialog to indecate the data transfering.What i am doing.checking how meny tables have to sync and getting all data with for loop and through the for loop call my AsyncTask().execute() Method. (code shows bellow)
Issue is when showing the progress dialog loop length is grater than 1 open several progress dialogs on top itselft and they are not close.But already i called close event
DataTransfering Method
private class NetworkTransfer extends AsyncTask<DataLocation, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(LocationFinder.this); // show ProgressDialog
pDialog.setMessage("Processing...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(DataLocation... arg0) {
NetworkUtil networkUtil = new NetworkUtil(); //my http connection class
DataLocation loc = arg0[0];
networkUtil.InsertDataEmp(loc.getC_device_modle(),
loc.getC_usercd(), loc.getC_brach());
DataSource dsx = new DataSource(getApplicationContext());
dsx.updateLocDt(loc.getC_brach()); // send data to webserver
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss(); // for dissmiss the ProgressDialog
}
Function to run execure() method in Button Click Event shows bellow.
public void sendAllUnSyncData() {
DataSource ds = new DataSource(getApplicationContext());
final List<DataLocation> data = ds.GetLocList();
for (int i = 0; i < data.size(); i++) {
final NetworkTransfer networkObject = new NetworkTransfer();
networkObject .execute(data.get(i)); // call AsyncTask Method
}
}
When Running this code if loop length is bigger than (i>1)one (1) Progress Dioalog not closed.But if it's equals to one (1) , (i==1)it's worked!
Also I was tryied with Thread,but result was same.
In your onPreExecute, try to add this:
protected void onPreExecute() {
super.onPreExecute();
if (pDialog == null || !pDialog.isShowing()){
pDialog = new ProgressDialog(LocationFinder.this); // show ProgressDialog
pDialog.setMessage("Processing...");
pDialog.setCancelable(false);
pDialog.show();
}
}
Then set 2 global variables: int dataSized and int dataDone=0.
Initiate dataSized in your sendAllUnSyncData like this:
public void sendAllUnSyncData() {
DataSource ds = new DataSource(getApplicationContext());
final List<DataLocation> data = ds.GetLocList();
dataSized=data.size();
for (int i = 0; i < data.size(); i++) {
final NetworkTransfer networkObject = new NetworkTransfer();
networkObject .execute(data.get(i)); // call AsyncTask Method
}
}
Then on your onPostExecute, do this:
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dataDone++;
if(dataDone==dataSized){
if (pDialog.isShowing())
pDialog.dismiss(); // for dissmiss the ProgressDialog
}
}
Let me know if it's working.
Could anyone help me on following questions.
1) onPostExecute - Toast.make while in background i am sending HttpRequest.
0nCraeteBunle - execute() ; startNewActivity
showing error. AsycTask# Runtime Exception .
While commenting Http request in background, no error is showed.
here, how can i know that http Request and reply finished , so that i can start my new Activity.
2) how to get HttpParams. Sending from TIBCO BE (As event with properties)
3) What if i am recieving JSONObject, JAVAObject, Integer other than String in onPostExecute. unable to override .
Try this,
protected class GetTask extends AsyncTask<Void, Void, Integer> {
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(MainActivity.this,
"Loading", "Please wait");
}
#Override
protected Integer doInBackground(Void... params) {
// TODO Auto-generated method stub
//call ur HttpRequest
httpRequest();
return 0;
}
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
mHandler.sendEmptyMessage(0);
}
}
Handler mHandler = new Handler() {
public void handleMessage(Message Msg) {
if (Flag) {
//Add ur stuff
}else{
}
And then in ur method set Flag value
public void httpRequest() {
// TODO Auto-generated method stub
String URL ="ADD UR URL";
try {
JSONObject ResponseObject = mAPIService.CallAPI(
YourActivity.this, URL);
String status = ResponseObject.getString("status");
Flag = true;
} catch (Exception err) {
Flag = false;
}
}
Below is an async class i created that i am trying to implement a dialog on execute and a Toast on complete.
How ever no toast or dialog are ever showing up.
my asykTask:
public class EmailPictureService extends HTTPRequestAsyncTask {
Context context;
ProgressDialog dialog;
public EmailPictureService(Context context){
this.context = context;
//dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Object... params) {
Log.v("Start EMAIL SERVICE","START YOPPPPPPPPPPPPPPPPPPPPPP!");
dialog = new ProgressDialog(context);
dialog.setMessage("Sending...");
dialog.setIndeterminate(true);
dialog.show();
HTTPInvoker invoker = new HTTPInvoker();
HttpResponse response = null;
EmailPicture emailPicture = new EmailPicture();
emailPicture.setDeviceType("TABLET");
emailPicture.setStoreId((String)params[1]);
emailPicture.setNotificationType("E");
emailPicture.setRecipientName((String)params[2]);
emailPicture.setRecipientEmail((String)params[3]);
String jsonString = JSONConverter.toJson(emailPicture);
response = invoker.invokePOSTFileService((String)params[0], jsonString, (File[])params[4]);
return parseHttpResponse(response);
}
#Override
protected void onPostExecute(String result) {
String msg = "";
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result != null) {
JSONObject jsonObject = null;
long errorCode = 0;
try {
jsonObject = new JSONObject((String) result);
errorCode = jsonObject.getLong("errorCode");
if(errorCode<1){
msg ="Success, your picture has been sent";
}else{
msg = "Sorry, there was an error sending your picture. Please try again later.";
}
Log.i(Constants.TAG, "Error Code...." + errorCode);
Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
toast.show();
} catch (JSONException e1) {
Log.i(Constants.TAG, "Exception...." + e1);
Toast toast = Toast.makeText(context, "Failure: "+e1, Toast.LENGTH_SHORT);
toast.show();
e1.printStackTrace();
}
}
}
}
how i call it from my activity:
new EmailPictureService(this).execute(url,storeID,cusName, cusEmail, new File[]{file});
my log
You should not attempt to access the UI from doInBackground(). The purpose of AsyncTasks and doInBackground() is avoid bogging down the UI thread... Instead you should preform the UI work in the appropriate methods: onPreExecute(), onProgressUpdate(), onPostExecute(), etc
I suspect the toast isn't showing because your result is always null. Your log shows an error on the post
As others have said, start your progress dialog from onPreExecute()
I note that you instantiate your progressDialog in doInBackground(). Move it to onPreExecute() instead. doInBackground() are only supposed to do non-UI work. =)
This should "solve" your problem.
I have a problem which I don't understand. I want to show a simple Progress Dialog in Android. So I created an AsyncTask and create the dialog in the constructor. I use the methods onPreExceution to initialise the dialog and the onPostExecute method I destory the dialog. So until now this looks total correct for me. But when I start the App on my Nexus 7 the dialog doesn't show up till the job is done. So it shows up for a half of a second at the end of the job... What am I doing wrong?
Thank you for your help ;)
public class ParseHTMLCodeNew extends AsyncTask<String, Void, String> {
ProgressDialog dialog;
public ParseHTMLCodeNew(Context context) {
dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
//einrichten des Wartedialogs
dialog.setTitle("Bitte warten!");
dialog.setMessage("Die Kommentare werden vom Server geladen.");
dialog.show();
}
#Override
protected String doInBackground(String params) {
InputStream is = null;
String data = "";
try
{
URL url = new URL( params[0] );
is = url.openStream();
data = new Scanner(is).useDelimiter("//html//").next();
}
catch ( Exception e ) {
e.printStackTrace();
}
return data;
}
#Override
protected void onPostExecute(String result) {
//Dialog beenden RSS Feed ist fertig geparst
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
}
UPDATE
This is my new AsyncTask:
public class ParseHTMLCodeNew extends AsyncTask<String, String, String> {
ProgressDialog dialog;
private final OnCompleteTaskListener onCompleteTaskListener;
public interface OnCompleteTaskListener {
void onComplete(String data);
}
public ParseHTMLCodeNew(Context context, OnCompleteTaskListener taskListener) {
onCompleteTaskListener = taskListener;
dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
//einrichten des Wartedialogs
dialog.setTitle("Bitte warten!");
dialog.setMessage("Die Kommentare werden vom Server geladen.");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
InputStream is = null;
String data = "";
try
{
URL url = new URL( params[0] );
is = url.openStream();
data = new Scanner(is).useDelimiter("//html//").next();
}
catch ( Exception e ) {
e.printStackTrace();
}
return data;
}
#Override
protected void onPostExecute(String result){
onCompleteTaskListener.onComplete(result);
//Dialog beenden RSS Feed ist fertig geparst
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
}
And i am calling it this way:
new ParseHTMLCodeNew(this,new OnCompleteTaskListener() {
#Override
public void onComplete(String data) {
gData = data;
}
}).execute(url);
As i commented on your post, data has no value.
If you calling this code so:
String data = new ParseHTMLCodeNew(CommentActivity.this).execute(url).get();
Then you do not really see your dialogue because there is a blocking UI.
Method get() waits if necessary for the computation to complete, and then retrieves its result.
Call so:
new ParseHTMLCodeNew(CommentActivity.this).execute(url);
and the result of the work is handled directly in the AsyncTask.
If you need to transfer the data to the main thread, you should tell him that the task was completed.
Wat is the simple code, I just added OnCompleteTaskListener interface
public class ParseHTMLCodeNew extends AsyncTask<String, Void, String> {
private final OnCompleteTaskListener onCompleteTaskListener;
private ProgressDialog dialog;
public interface OnCompleteTaskListener {
void onComplete(String data);
}
public ParseHTMLCodeNew(Context context, OnCompleteTaskListener taskListener) {
onCompleteTaskListener = taskListener;
dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
// einrichten des Wartedialogs
dialog.setTitle("Bitte warten!");
dialog.setMessage("Die Kommentare werden vom Server geladen.");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();
// your code here
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(100);
sb.append(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return sb.toString();
}
#Override
protected void onPostExecute(String result) {
// Dialog beenden RSS Feed ist fertig geparst
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
onCompleteTaskListener.onComplete(result);
}
}
And the example of a call
new ParseHTMLCodeNew(this,new OnCompleteTaskListener() {
#Override
public void onComplete(String data) {
Toast.makeText(CommentActivity.this, data, Toast.LENGTH_LONG).show();
}
}).execute("your_url");
Be careful, this code can produce errors when you rotate your Phone.
When Activity destroyed but task is performed:
- progress dialog will close and will not open again
- local variable to dialog or context is incorrect.
If the operation is performed for a long time can make it through the of the services?
I've wrote a code that get data from online database and populate that data in lisview here is the part of my code hope that help !
class LoadMyData extends AsyncTask<String, String, String> {
//Before starting background thread Show Progress Dialog
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getParent());
pDialog.setMessage("Loading. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
//Your code here
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting the data
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// In my case use my adapter to display the data in a listview
adapter = new MyAdaper();
list.setAdapter(adapter);
}
});
}
}
Progress dialog should be shown from UI thread
runOnUiThread(new Runnable() {
public void run() {
dialog.setTitle("Bitte warten!");
dialog.setMessage("Die Kommentare werden vom Server geladen.");
dialog.show();
}});