Handle long time network oparation with android - android

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.

Related

Android OS on network main thread exception [duplicate]

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.

Dismiss a progressdialog and trigger another one

my goal is to dismiss the initial progressdialog if there's no internet connection (let's say after 10 seconds) and then trigger another alertdialog whice prompts the user to check his internet connection and try again.
here is my RemoteDataTask class :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
/*
Create the progressdialog
*/
mProgressDialog = new ProgressDialog(MainActivity.this);
//title :
mProgressDialog.setTitle("SmartShop. Shopping made easy !");
//message :
mProgressDialog.setMessage("Chargement...");
mProgressDialog.setIndeterminate(false);
//show the progressdialog...Only if gpslocation is available !! :)
if (gps.canGetlocation()){
mProgressDialog.show();
}
//mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
long delayInMillis = 3000;
list_of_articles = new ArrayList<Articles>();
try {
timer.schedule(new TimerTask() {
#Override
public void run() {
mProgressDialog.dismiss();
}
},delayInMillis );
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
// Locate the column named "ranknum" in Parse.com and order list
// by ascending
//query.orderByAscending("ranknum");
query.whereWithinKilometers("Localisation_Vendeur",device_location,rayon);
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("Image_Article");
Articles map = new Articles();
map.setArticle_name((String) article.get("Nom_Article"));
map.setArticle_vendor((String) article.get("Nom_Vendeur"));
//map.setArticle_vendor((String) article.get("reduction"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
my progressdialog does not dismiss with this code. what's wrong with it ? and where should I call the second alertdialog "check internet connection and try again" ?
Thanks !
You should perform UI modifications only from the UI thread. Timer runs its tasks in its own thread, not in the UI thread. You can do something like this:
runOnUiThread(new Runnable() { public void run() {
mProgressDialog.dismiss();
}});
And start a new dialog in the same way.

keep a ProgessDialog until the callback is executed

im using the azure mobile service. I have some users in the db i want to authenticate, and in order to do that, I execute a query to get a User after you enter a username and a password and press OK. When OK is pressed, if all it's well an intent should be started. How can I display a ProgressDialog until the callback method of the executed query is completed?
EDIT: the problem is that i have a button(logIn button) and when you click it, it will build a query and execute it in an async task, hence my problem. If i just add a progress dialog the call flow will move on since from the onClickListener point of view, the action has finished.
Just show() it before you call the query and dismiss() it in the callback method.
As your using the AsyncTask to query the data , use the onPreExecute and onPostExecute methods to show/dismiss the ProgressDialog.
Create a class which extends the AsyncTask , like this . In the onPreExecute show the ProgressDialog and when your done with fetching the data in doInBackground , in onPostExecute dismiss the dialog
public class QueryTask extends AsyncTask<Void,Void,Object> {
private ProgressDialog progressDialog = null;
private final Context mContext;
public QueryTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(mContext);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// do your stuff to query the data
return null;
}
#Override
protected void onPostExecute(Object result) {
progressDialog.dismiss();
// do your other stuff with the queried result
}
#Override
protected void onCancelled(Object result) {
progressDialog.dismiss();
}
}
Finally, when button onClick execute the task
new QueryTask(YourActivity.this).execute();
This example code was used by me to load all the events from an SQL database. Until the app gets the data from the server, a progress dialog is displayed to the user.
class LoadAllEvents extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_events,
"GET", params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// products found
// Getting Array of Products
Events = json.getJSONArray(TABLE_EVENT);
// looping through All Contacts
for (int i = 0; i < Events.length(); i++) {
JSONObject evt = Events.getJSONObject(i);
// Storing each json item in variable
id = evt.getString(pid);
group = evt.getString(COL_GROUP);
name = evt.getString(COL_NAME);
desc = evt.getString(COL_DESC);
date = evt.getString(COL_DATE);
time = evt.getString(COL_TIME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(pid, id);
map.put(COL_GROUP, group);
map.put(COL_NAME, name);
map.put(COL_DESC, desc);
map.put(COL_DATE, date);
map.put(COL_TIME, time);
// adding HashList to ArrayList
eventsList.add(map);
}
} else {
// Options are not available or server is down.
// Dismiss the loading dialog and display an alert
// onPostExecute
pDialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(getActivity(),
eventsList, R.layout.list_item, new String[] {
pid, COL_GROUP, COL_NAME, COL_DATE, COL_TIME },
new int[] { R.id.pid, R.id.group, R.id.name, R.id.header,
R.id.title2 });
setListAdapter(adapter);
}
});
}
hope this helps.

Progress Dialog only shows up when the job is already done

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();
}});

Unable to dismiss progress bar in AsyncTask

I want to load datas from a list to gridview with a loading effect using progressbar.Im getting items from a webservice.The problem i face is im unable to dismiss the progress bar even after showing the gridview.I can see the gridview with items but progress bar is still running .What am i doing wrong here.
private void testAsyncTask() {
Log.e("Im in testAsyncTask()", "");
new AsyncTask<Object, Object, Object>() {
#Override
protected void onPreExecute() {
progress_Dialog = ProgressDialog.show(a, "", "Loading");
Log.e("Im in onPreExecute", "");
// super.onPreExecute();
}
#Override
protected Integer doInBackground(Object... params) {
MenuService menuService = new MenuServiceImpl();
PartnerMenuServiceResponse partnerMenu = menuService
.getPartnerMenu();
jewellist = partnerMenu.getMenu().getMenuEntries();
Log.e("Im in doInBackground", "");
System.gc();
return 0;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// super.onPostExecute(result);asd
Log.e("Im in onPostExecute", "");
if (progress_Dialog.isShowing()) {
progress_Dialog.dismiss();
}
ShopGridAdapter adapter = new ShopGridAdapter(ShopGridActivity.this, jewellist);
AllJewelgridView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//AllJewelgridView.setAdapter(new ShopGridAdapter(
// ShopGridActivity.this, jewellist));
if (AllJewelgridView.getCount() <= 0) {
MyAlertDialog.ShowAlertDialog(ShopGridActivity.this, "",
"No data found.", "OK");
}
progress_Dialog.dismiss();
}
}.execute();
}
#Override
protected void onPreExecute() {
progress_Dialog = new ProgressDialog(context);
progress_Dialog.setMessage("Loading...");
progress_Dialog.show();
}
EDIT :
#Override
protected void onPostExecute(Object result) {
Log.e("Im in onPostExecute", ""); <------ ARE YOU ABLE SEE THIS IN logcat ?
progress_Dialog();
}
It may possible onPostExecute() not called. So to confirm check logcat
You need to put some code in your AsyncTask
ProgressDialog progress=null;
progress=ProgressDialog.show(this,"title","loading..").show();//put this code in onPreExecute()
progress.dismiss();//put this code in onPostExecute()
for more ProgressBar while loading ListView (using AsyncTask)
You can write in onPostExecute method may help you.
if ( progress_Dialog != null) {
progress_Dialog.cancel();
}

Categories

Resources