Handle threads on Android UI - android

In my application I want to check the network status on device,If no network connectivity is detected on device the i want to show a toast saying no network connection and then exit the application.And if the connection is detected on device then i have to load a list from webservice and display it on screen
I have done following code in onCreate function of application.It is running on emulator but not on real device.The reason for this to showANR on device is i am trying to handle so many threads on UI which is not appreciated in android.Please guide me how to do this using AsyncTask.
any code snippet or link to tutorial or suggestions will be helpful to me
boolean connected = false;
ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivitymanager.getActiveNetworkInfo();
connected = networkinfo != null && networkinfo.isAvailable()
&& networkinfo.isConnected();
Log.v("Message ", connected + "");
Log.v("Message ", networkinfo.getReason());
//Toast.makeText(CategoryActivity.this, connected + "", 2000).show();
//connected = false;
Log.v("Message 1", connected + "");
if (connected == false) {
CategoryActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// Log.v("Message ", connected + "");
Toast.makeText(CategoryActivity.this,
"No Internet Connection detected on device", 3000).show();
}
});
Handler handler1 = new Handler();
handler1.postDelayed(new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
}), 4000);
} else {
CategoryArray = new JSONArray();
final ProgressDialog pd = ProgressDialog.show(
CategoryActivity.this, "", "Loading...", false, true);
pd.setIcon(getResources().getDrawable(R.drawable.icon));
new Thread() {
public void run() {
try {
sleep(5000);
// Log.v("TAG","in try block");
} catch (Exception e) {
// Log.e("tag", e.getMessage());
}
pd.dismiss();
// Log.v("TAG","progress dismiss");
}
}.start();
handler.postDelayed(new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
CategoryArray = CW
.getCategory("http://www.balajeebazaar.com/RestServiceImpl.svc/categorydetails");
// TODO: handle exception
for (int i = 0; i <= CategoryArray.length() - 1; i++) {
try {
String[] val = new String[3];
Log.v("category array : ",
CategoryArray.getString(i));
val = CategoryArray.getString(i).split(",");
CategoryID.add(i, val[0]);
CategoryList.add(i, val[1]);
val = null;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
adapter = new CategoryListAdapter(CategoryActivity.this,
CategoryList);
list.setAdapter(adapter);
}
}), 5000);
Thanks
EDIT
ERROR/AndroidRuntime(5486): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
ERROR/AndroidRuntime(5486): java.lang.RuntimeException: An error occured while executing doInBackground()
ERROR/AndroidRuntime(5486): at android.os.AsyncTask$3.done(AsyncTask.java:200)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask.run(FutureTask.java:122)
ERROR/AndroidRuntime(5486): at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
ERROR/AndroidRuntime(5486): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
ERROR/AndroidRuntime(5486): at java.lang.Thread.run(Thread.java:1060)
ERROR/AndroidRuntime(5486): Caused by: java.lang.ArrayIndexOutOfBoundsException
ERROR/AndroidRuntime(5486): at com.ecommerce.balajeebazaar.CategoryActivity$Loader.doInBackground(CategoryActivity.java:181)
ERROR/AndroidRuntime(5486): at com.ecommerce.balajeebazaar.CategoryActivity$Loader.doInBackground(CategoryActivity.java:1)
ERROR/AndroidRuntime(5486): at android.os.AsyncTask$2.call(AsyncTask.java:185)
11-18 18:30:07.582: ERROR/AndroidRuntime(5486):
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
ERROR/AndroidRuntime(5486): 4 more

I suggest you read up on the AsyncTask yourself before applying the solution I have posted below, in order to better understand what is going on.
This is what you need in your Activity (it must replace all the code you posted):
boolean connected = false;
ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivitymanager.getActiveNetworkInfo();
connected = networkinfo != null && networkinfo.isAvailable()
&& networkinfo.isConnected();
Log.v("Message ", connected + "");
Log.v("Message ", networkinfo.getReason());
//Toast.makeText(CategoryActivity.this, connected + "", 2000).show();
//connected = false;
Log.v("Message 1", connected + "");
if (connected == false) {
Toast.makeText(CategoryActivity.this, "No Internet Connection detected on device", Toast.LENGTH_LONG ).show();
finish();
} else {
new Loader().execute();
}
This is the AsyncTask which should be an inner class of your Activity:
private class Loader extends AsyncTask<Void, Void, Void> {
final ProgressDialog pd;
#Override
protected void onPreExecute() {
pd = ProgressDialog.show( CategoryActivity.this, "", "Loading...", false, true);
pd.setIcon(getResources().getDrawable(R.drawable.icon));
super.onPreExecute();
}
#Override
protected Void doInBackground( Void... arg0 ) {
CategoryArray = new JSONArray();
CategoryArray = CW.getCategory("http://www.balajeebazaar.com/RestServiceImpl.svc/categorydetails");
for (int i = 0; i <= CategoryArray.length() - 1; i++) {
try {
String[] val = new String[3];
Log.v("category array : ", CategoryArray.getString(i));
val = CategoryArray.getString(i).split(",");
CategoryID.add(i, val[0]);
CategoryList.add(i, val[1]);
val = null;
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter = new CategoryListAdapter(CategoryActivity.this, CategoryList);
return null;
}
#Override
protected void onPostExecute( Void result ) {
pd.dismiss();
list.setAdapter(adapter);
super.onPostExecute( result );
}
}
Note
I wasn't able to check if the above actually works - but it should put you on the right track.

A nice tutorial on AsyncTasks and Handlers.
In really short, the idea of AsyncTask - you make a private class which extends AsyncTask in your Activity.
Doing this, you automatically get access to this Activities UI Thread from the AsyncTask class.
In AsyncTaks there are a couple of methods you should pay attention to. They are explained here.
What you should know is that only doInBackground() is executed in a separate Thread. Everything else is invoked on the UI thread of the Activity, where your AsyncTask is defined.
Simple scenario:
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// stuff
new MyAsyncTask().execute(); //this should be invoked only once
}
private class MyAsyncTask() extends AsyncTask<Void, Void, <TypeOfResult Or Void>> {
#Override //executed on the UI thread of MyActivity
protected void onPreExecute() {
super.onPreExecute();
//prepare some stuff
}
#Override //executed in a separate Thread. This thread is automatically handled by AsyncTask
protected <TypeOfResult or Void> doInBackground(Void... params) {
//long operation
}
#Override //executed on the UI thread of MyActivity
protected void onPostExecute(<TypeOf Result Or Void>) {
super.onPostExecute(result);
// do stuff with result from long operation
}
}
}

You don't necessarily need an AsyncTask, you can use regular Java threading to accomplish what you need (far easier for a background task like this).

Related

How to set a fixed time if AsyncTask is not finished

I have an asynctask and I'm looking to do a wait if the async is taking too long, I'm downloading some data of the database , but I don't want to have the user looping around the progressdialog, I want to set a fixed time, lets say I'm downloading a file but is taking forever, so I tell the user, "hey, check your internet connection and try again" I'm looking to do this with a timer, but I'm kinda stuck, this is where I do my asynctask
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
String s;
public DownloadFilesTask(String s){
this.s = s;
}
#Override
protected Void doInBackground(Void... voids) {
DownloadMethod(s);
return null;
}
}
so let's say I want to execute that downloadmethod for a fixed time, 10 or 20 seconds, if the file is not downloaded at that time I return a message to the user saying that he needs to check for hes internet.
You can use handler to run after a definite amount time and maintain a boolean flag which you can update in postExecute function of async task.
In your activity/fragment class:
new Handler().postDelayed(new Runnable(){
public void run(){
//Check whether the flag has been updated or not
},1000)
You can use BroadcastReceiver to listen your internet connection. Here is an example:
public class NetworkControl extends BroadcastReceiver {
static boolean isConnected = false;
#Override
public void onReceive(final Context context, final Intent intent) {
isNetworkAvailable(context);
}
private boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
if(!isConnected){
isConnected = true;
Toast.makeText(context, "You're online!!", Toast.LENGTH_LONG).show();
}
return true;
}
}
}
}
isConnected = false;
Toast.makeText(context, "Connection interrupted.", Toast.LENGTH_LONG).show();
return false;
}
}
Also you need some permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Then start the service in your activity.
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
receiver = new NetworkControl();
registerReceiver(receiver, filter);
If you are using HttpURLConnection to download the file then you can do something like this:
private class DownloadFilesTask extends AsyncTask<String, Integer, Integer> {
#Override
protected Integer doInBackground(String... ulr) {
URL url = null;
try {
url = new URL(ulr[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setConnectTimeout(2000); //Timeout
//...Other codes for downloading
return 101;
} catch (java.net.SocketTimeoutException e) {
return 102;
} catch (MalformedURLException e) {
return 103;
} catch (IOException e) {
return 104;
}
}
#Override
protected void onPostExecute(Integer result) {
if(result == 102) {
Toast.makeText(getApplicationContext(), "Connection Timeout.", Toast.LENGTH_LONG).show();
}
}
}
First thing I want to say that is, while running downloading task it's not a good practice, to message a user that check your internet connection or
no internet connection. Because in this condition, if user do switch off then on network connection then your downloading task restarts again and takes whole time again. So, avoid this types of messages.
Now about solution, after execute background task you can check your task is running or completed. If it takes too much time
then show a message. For example,
YourBackgroundTask task = new YourBackgroundTask();
task.execute();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (task.getStatus == AsyncTask.Status.RUNNING){
Toast.makeText(this, "Please wait...", Toast.LENGTH_SHORT).show();
}
}
},20000); // time in milisecond
And if you want to repeat this, you can easily re-run handler.
Here is a basic idea you can try if it works
private class DownloadFilesTask extends AsyncTask<Void, Integer, Void> implements TimerTask{
String s;
Timer timer;
Object objectResult;
public DownloadFilesTask(String s){
this.s = s;
timer = new Timer();
}
#Override
protected Void doInBackground(Void... voids) {
objectResult = DownloadMethod();
return null;
}
private Object DownloadMethod() {
//here implement the download logic and return the object
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
// your code to update progress
}
public void checkProgress(){
timer.schedule(this,2000);
}
#Override
public void run() {
if (objectResult!=null){
//download completed
}else{
//show dialog here and schedule a task again
timer.schedule(this,2000);
}
}
}

Error in thread

I am getting error in doing a internet resource getting in thread .
i get this error in logcat :
09-04 21:05:32.916 1480-1493/abc.digicare.sms1 E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-78
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast$TN.<init>(Toast.java:317)
at android.widget.Toast.<init>(Toast.java:91)
at android.widget.Toast.makeText(Toast.java:233)
at abc.digicare.sms1.MyActivity$1.run(MyActivity.java:45)
at java.lang.Thread.run(Thread.java:856)
my code is this : calling this function from a button click .
public void GetData(View v) {
Toast.makeText(getApplicationContext(), "first", Toast.LENGTH_SHORT).show();
p=ProgressDialog.show(getApplicationContext(),"Digicare","Wait . . .");
try {
Runnable myrun = new Runnable() {
#Override
public void run() {
String acc = "";
if (chckbx_cus.isChecked() && !(chckbx_ven.isChecked()) && !(chckbx_emp.isChecked())) {
acc = "cus";
} else if (chckbx_ven.isChecked() && !(chckbx_cus.isChecked()) && !(chckbx_emp.isChecked()))
Toast.makeText(getApplicationContext(), acc, Toast.LENGTH_SHORT).show();
final String facc = acc;
GetList GL = new GetList();
//Toast.makeText(getApplicationContext(),txt_ip.getText(),Toast.LENGTH_SHORT).show();
obj = GL.GetAccounts(getApplicationContext(), facc, "GetAccounts", "192.168.1.111");
mhandler.sendEmptyMessage(0);
}
};
Thread th = new Thread(myrun);
th.start();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "from here " + e.toString(), Toast.LENGTH_LONG).show();
}
mhandler = new Handler() {
#Override
public void handleMessage(Message msg) {
p.dismiss();
}
};
}
the function which is called from other class is for getting data from a asp.net web service
It seems that you are trying to display a Toast from a background thread. Move the Handler creation code before the try-catch block and use a final modifier so that you can access the handler from within the Runnable. Then in the runnable call
mhandler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), acc, Toast.LENGTH_SHORT).show();
}
});

AsyncTask.get() no progress bar

My app sends data to the server. It generally works fine until the user is in a bad signal area. If the user is in a good signal area the the following code works fine and the data is sent.
String[] params = new String[]{compID, tagId, tagClientId, carerID,
formattedTagScanTime, formattedNowTime, statusForWbService, getDeviceName(), tagLatitude, tagLongitude};
AsyncPostData apd = new AsyncPostData();
apd.execute(params);
.
private class AsyncPostData extends AsyncTask<String, Void, String> {
ProgressDialog progressDialog;
String dateTimeScanned;
#Override
protected void onPreExecute()
{
// progressDialog= ProgressDialog.show(NfcscannerActivity.this,
// "Connecting to Server"," Posting data...", true);
int buildVersionSdk = Build.VERSION.SDK_INT;
int buildVersionCodes = Build.VERSION_CODES.GINGERBREAD;
Log.e(TAG, "buildVersionSdk = " + buildVersionSdk
+ "buildVersionCodes = " + buildVersionCodes);
int themeVersion;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
themeVersion = 2;
}else{
themeVersion = 1;
}
progressDialog = new ProgressDialog(NfcscannerActivity.this, themeVersion);
progressDialog.setTitle("Connecting to Server");
progressDialog.setMessage(" Sending data to server...");
progressDialog.setIndeterminate(true);
try{
progressDialog.show();
}catch(Exception e){
//ignore
}
};
#Override
protected String doInBackground(String... params) {
Log.e(TAG, "carerid in doinbackground = " + params[3] + " dateTimeScanned in AsyncPost for the duplecate TX = " + params[4]);
dateTimeScanned = params[4];
return nfcscannerapplication.loginWebservice.postData(params[0], params[1], params[2], params[3], params[4],
params[5], params[6], params[7] + getVersionName(), params[8], params[9]);
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
try{
progressDialog.dismiss();
}catch(Exception e){
//ignore
}
if( result != null && result.trim().equalsIgnoreCase("OK") ){
Log.e(TAG, "about to update DB with servertime");
DateTime sentToServerAt = new DateTime();
nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerAt,null);
nfcscannerapplication.loginValidate.insertIntoDuplicateTransactions(dateTimeScanned);
tagId = null;
tagType = null;
tagClientId = null;
//called to refresh the unsent transactions textview
onResume();
}else if(result != null && result.trim().equalsIgnoreCase("Error: TX duplicated")){
Log.e(TAG, "response from server is Duplicate Transaction ");
//NB. the following time may not correspond exactly with the time on the server
//because this TX has already been processed but the 'OK' never reached the phone,
//so we are just going to update the phone's DB with the DupTX time so the phone doesn't keep
//sending it.
DateTime sentToServerTimeWhenDupTX = new DateTime();
nfcscannerapplication.loginValidate.updateTransactionWithServerTime(sentToServerTimeWhenDupTX,null);
tagId = null;
tagType = null;
tagClientId = null;
}else{
Toast.makeText(NfcscannerActivity.this,
"No phone signal or server problem",
Toast.LENGTH_LONG).show();
}
}
}//end of AsyncPostData
.
The app in bad signal areas tends to show the progress bar for a few minutes before showing a black screen for a while rendering the app unusable.
I thought a way around this would be to do the following.
String[] params = new String[]{compID, tagId, tagClientId, carerID,
formattedTagScanTime, formattedNowTime, statusForWbService, getDeviceName(), tagLatitude, tagLongitude};
AsyncPostData apd = new AsyncPostData();
try {
apd.execute(params).get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This will cause the AsyncTask to cancel after 10 seconds, but as it is executing there is a black screen until the data is sent followed by the progressbar for a few millisecs.
Is there a way to show the progressbar whilst executing an AsyncTask.get()?
thanks in advance. matt.
Also are there any ideas why the black screen comes when the user is in bad signal area and therefor no response from the server. This senario seems to cause the app alot of problems where it's behavior is unusual afterwards like sending extra transactions at a later date.
[edit1]
public class SignalService extends Service{
NfcScannerApplication nfcScannerApplication;
TelephonyManager SignalManager;
PhoneStateListener signalListener;
private static final int LISTEN_NONE = 0;
private static final String TAG = SignalService.class.getSimpleName();
#Override
public void onCreate() {
super.onCreate();
// TODO Auto-generated method stub
Log.e(TAG, "SignalService created");
nfcScannerApplication = (NfcScannerApplication) getApplication();
signalListener = new PhoneStateListener() {
public void onSignalStrengthChanged(int asu) {
//Log.e("onSignalStrengthChanged: " , "Signal strength = "+ asu);
nfcScannerApplication.setSignalStrength(asu);
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
// TODO Auto-generated method stub
Log.e(TAG, "SignalService destroyed");
SignalManager.listen(signalListener, LISTEN_NONE);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// TODO Auto-generated method stub
Log.e(TAG, "SignalService in onStart");
SignalManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
SignalManager.listen(signalListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
You do not need a timer at all to do what you're attempting (for some reason I thought you were trying to loop the AsyncTask based on your comments above which resulted in mine.). If I understand correctly you're issue is with the loss of service. You have an AsyncTask that you start which may or may not finish depending on certain conditions. Your approach was to use get and cancle the task after a fixed time in the event that it did not finish executing before then - the assumption being if the task didn't finish within the 10 second cut off, service was lost.
A better way to approach this problem is to use a boolean flag that indcates whether network connectivity is available and then stop the task from executing if service is lost. Here is an example I took from this post (I apologize for the formatting I'm on a crappy computer with - of all things - IE8 - so I can't see what the code looks like).
public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
private final ProgressDialog progressDialog;
public MyTask(Context ctx) {
progressDialog = gimmeOne(ctx);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// actually could set running = false; right here, but I'll
// stick to contract.
cancel(true);
}
});
}
#Override
protected void onPreExecute() {
progressDialog.show();
}
#Override
protected void onCancelled() {
running = false;
}
#Override
protected Void doInBackground(Void... params) {
while (running) {
// does the hard work
}
return null;
}
// ...
}
This example uses a progress dialog that allows the user to cancle the task by pressing a button. You're not going to do that but rather you're going to check for network connectivty and set the running boolean based on whether your task is connected to the internet. If connection is lost - running will bet set to false which will trip the while loop and stop the task.
As for the work after the task complete. You should NEVER use get. Either (1) put everything that needs to be done after the doInBackgroundCompletes in onPostExecute (assuming its not too much) or (2) if you need to get the data back to the starting activity use an interface. You can add an interface by either adding as an argument to your tasks constructor or using a seperate method that sets the interface up. For example
public void setInterface(OnTaskComplete listener){
this.listener = listener;
}
Where OnTaskComplete listener is declared as an instance variable in your AsyncTask. Note the approach I am describing requires using a seperate AsyncTask class. Your's is private right now which means you need to change your project a little.
UPDATE
To check connectivity I would use something like this.
public boolean isNetworkOnline() {
boolean status=false;
try{
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getNetworkInfo(0);
if (netInfo != null && netInfo.getState()==NetworkInfo.State.CONNECTED) {
status= true;
}else {
netInfo = cm.getNetworkInfo(1);
if(netInfo!=null && netInfo.getState()==NetworkInfo.State.CONNECTED)
status= true;
}
}catch(Exception e){
e.printStackTrace();
return false;
}
return status;
}
You can check to see if there is an actual network connection over which your app can connect to ther server. This method doesn't have to be public and can be part of you're AsyncTask class. Personally, I use something similar to this in a network manager class that I use to check various network statistics (one of which is can I connect to the internet).
You would check connectivity before you started executing the loop in your doInBackground method and then you could periodicly update throughout the course of that method. If netowkr is available the task will continue. If not it will stop.
Calling the AsyncTask built in cancle method is not sufficient becuase it only prevent onPostExecute from running. It does not actually stop the code from execting.

android app shows blank screen (not updating ui) while in a loop

In my application, a client is connected to server. It waits until the connection to the server occurs. During that time the application is not responding. How can i solve this problem. Tried code snippet shows below
public Connection(){
client.SetParent(this);
this.context = g.getContext();
bConnected = false;
mNetworkRunner = new Runnable() {
public void run() {
try {
Log.e("", "mNetworkRunner...");
if( SendKeepAlive()){
Main.conStatus(1);
Log.e("", "SendKeepAlive...");
}
else {
Main.conStatus(0);
Log.e("", "No connection...");
g.log("Connection to server is lost... Trying to Connect...");
while(true){
Log.e("", "In while loop...");
if(!Connect()){
g.log("Trying...");
Log.e("", "In Connect no connect...");
Thread.sleep(2000);
}
else {
g.log("Connected");
break;
}
}
Main.conStatus(1);
}
mNetworkHandler.postDelayed(this, 30000);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
}
//
private void CheckNetworkConnection(){
if( mNetworkHandler == null ){
mNetworkHandler = new Handler();
mNetworkHandler.post(mNetworkRunner);
Log.e("", "CheckNetworkConnection...");
}
}
You are doing a lot of time consuming work in UI Thread, which create problem. In this situation you should use AsyncTask.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
//do your time consuming task here
}
protected void onProgressUpdate(Integer... progress) {
//setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//showDialog("Downloaded " + result + " bytes");
}
}
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
mNetworkHandler = new Handler() will make Runnable execute on UI Thread, you need HandlerThread
private void CheckNetworkConnection(){
if( mNetworkHandler == null ){
HandlerThread handlerThread = new HandlerThread("thread");
handlerThread.start();
mNetworkHandler = new Handler(handlerThread.getLooper());
mNetworkHandler.post(mNetworkRunner);
Log.e("", "CheckNetworkConnection...");
}
}

How to handle exception in AsyncTask

I am using AsyncTask like this
public class AccountReportActivity extends Activity {
private OrgaLevelTask orgaLevelTask;
public void onCreate(Bundle savedInstanceState) {
......
orgaLevelTask = new OrgaLevelTask(AccountReportActivity.this, spinner_orgaLevel, spinner_branch, txt_extra, txt_extra1);
orgaLevelTask.execute();
} //end of onCreate
} //end of class AccountReportActivity
task:
public class OrgaLevelTask extends AsyncTask<Void, Void, ArrayList<OrgaLevel>> {
//Constrcutor
public OrgaLevelTask(AccountReportActivity accountReportActivity, Spinner spinner_orgaLevel, Spinner spinner_branch, TextView txt_extra, TextView txt_extra1) {
this.accountReportActivity = accountReportActivity;
this.spinner_orgaLevel = spinner_orgaLevel;
....
} //end of constructor
#Override
protected ArrayList<OrgaLevel> doInBackground(Void... arg0) {
return callWebService();
} //end of doInBackground()
private ArrayList<OrgaLevel> callWebService() {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
......
} catch (SocketTimeoutException e) {
Toast.makeText(accountReportActivity, "Service is not connected, Please make sure your server is running", Toast.LENGTH_LONG).show();
return null;
} catch(Exception e) {
e.printStackTrace();
System.out.println();
}
} //end of callWebService()
} //end of class OrgaLevelTask
My this task call another AsyncTask which has the same code. The problem is if server is running then everything fine. But if server is not running and i call the web service then i get the exception that Force Application close. Why? I am handling SocketTimeoutException IF exception happens then i am saying that show toast on my Activity but why it is force closing the application. How can i handle it? Thanks
You can check the internet connection this way first
public static boolean checkConnection(Context context) {
final ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo netInfo = mConnectivityManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else
return false;
}
In this method
// Checking the internet connection
if (!InternetConnectionCheck.checkConnection(this)) {
Utilities.alertDialogBox(this, R.string.Title_String,
R.string.No_Internet_connection_String);
} else {
orgaLevelTask = new OrgaLevelTask(AccountReportActivity.this, spinner_orgaLevel, spinner_branch, txt_extra, txt_extra1);
orgaLevelTask.execute();
}
you should not use use Toast in doInBackground
catch (SocketTimeoutException e) {
Toast.makeText(accountReportActivity, "Service is not connected, Please make sure your server is running", Toast.LENGTH_LONG).show(); //<----------------------

Categories

Resources