Can't cancel doInBackground process in AsyncTask even using cancel method - java

I have declared instance of FileUploadTask which extends AsyncTask in onCreate() method
FileUploadTask uploadTask= null;
and executes the background method by following code
public class UploadFiles implements OnClickListener{
....
if(SOTCNetStat.chkConnectionStatus(UploadResult.this)){
uploadTask=new FileUploadTask();
uploadTask.execute("");
}
else
{
Toast.makeText(UploadResult.this, getResources().getString(R.string.Text_CheckNetworkConnections) , Toast.LENGTH_LONG).show();
}
....
}
Having a cancel button to cancel the background process
cancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d(TAG,"cancel button clicked.....");
//FileUploadTask uploadTask= new FileUploadTask();
if(uploadTask!=null)
{
Log.d(TAG,"click event null checking....");
uploadTask.cancel(true);
}
}
}
In FileUploadTask class declared a boolean to check the running status
public class FileUploadTask extends AsyncTask<String, Integer, String> {
....
boolean isRunning=true;
The doInBackground method
#Override
protected String doInBackground(String... arg0) {
for(int i=0; i<fp.size(); i++){
index = i+1;
if(isCancelled() && !isRunning)
{
Log.d(TAG,"Cancel 1 Condition Checked ["+i+"]");
Log.d(TAG,"doInBackground canceled");
break;
}
else
{
Log.d(TAG,"Cancel 1 Canceled ["+i+"]");
}
file1 = new File(fp.get(i));
String urlString = Constants.UPLOAD_URL;
try {
Log.e("doInBackground", "urlString: " + urlString);
Log.e("doInBackground", "domainPref: " + domainName);
urlString = urlString.replace("domain", URLEncoder.encode(domainName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
FileBody bin1 = new FileBody(file1);
ProgressMultipart reqEntity = new ProgressMultipart(new ProgressListener() {
#Override
public void transferred(long num) {
//publishProgress((int) ((num / (float) file1.length() ) * 100));
publishProgress((int) ((num / (float) totalSize ) * 100));
}
});
reqEntity.addPart("userfile", bin1);
if(getIntent().hasExtra("show_id"))
{
//String showId = getIntent().getStringExtra("show_id");
reqEntity.addPart("mobileshow", new StringBody("1"));
reqEntity.addPart("show_ids", new StringBody(getIntent().getStringExtra("show_id")));
}
reqEntity.addPart("Filename", new StringBody(file1.getName()));
reqEntity.addPart("user_id", new StringBody("2"));
reqEntity.addPart("privateasset", new StringBody("true"));
reqEntity.addPart("uploadtype", new StringBody("Normal"));
reqEntity.addPart("version_num", new StringBody("1"));
totalSize = reqEntity.getContentLength();
post.setEntity(reqEntity);
System.err.println("post :"+post.toString());
//to be check the cancel operation
if(isCancelled() && !isRunning)
{
Log.d(TAG,"Cancel 2 Condition Checked ["+i+"]");
Log.d(TAG,"File Uploading Cancelled in doInBackground method");
break;
}
else
{
Log.d(TAG,"Cancel 2 Canceled ["+i+"]");
}
HttpResponse response = client.execute(post);
resEntity = response.getEntity();
response_str = EntityUtils.toString(resEntity);
}
....
return response_str;
}
and overloaded onCancelled methods
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
Log.d(TAG,"onCancelled() method called");
super.onCancelled();
}
#Override
protected void onCancelled(String result) {
// TODO Auto-generated method stub
Log.d(TAG,"onCancelled(String) method called");
isRunning=false;
this.cancel(true);
}
I tried a lot and explored . Even using cancel method I can't able to stop the uploading process in background. Please any one give solutions to the problem
Some links i referred
http://www.technotalkative.com/cancel-asynctask-in-android/
http://developer.android.com/reference/android/os/AsyncTask.html

You seem to be missing how AsyncTask works. The onCancelled() method will only be called after doInBackground() is finished, similar to the onPostExecute() method. It is not called immediately after uploadTask.cancel(true) is called as you think it will be. The way you are using it, you have no need for onCancelled() methods or an isRunning variable (currently in your code isRunning is never changed to false and thus your isCancelled() check never works). Remove both the onCancelled() methods and the isRunning variable and your AsyncTask will work.

check this, after canceling the asynctask write this condition.
if(asynctask.iscancel()){
break;
}
it may help for u. :)
http://developer.android.com/reference/android/os/AsyncTask.html

Related

how to call method with an asynctask after button is clicked

How can you call a method within an AsyncTask? In my asynctask,which is an inner class in my java file 'xyz', when the user clicks a button, it should call a method within 'xyz' which also happens to be an alertDialog, i know it calls it, but when it reaches the method, the app crashes and gives a runtime exception, which says 'Can't create handler inside thread that has not called Looper.prepare()'. I looked up examples here but it threw the same runtime exception. How can i make it work? isn't calling an outer method from within the asynctask a possibility?
this is the snippet to call the method:
private class DownloadFilesTask extends AsyncTask<Void,Void,Void> {
private LoginActivity loginActivity;
public DownloadFilesTask(LoginActivity loginActivity){
this.loginActivity=loginActivity;
}
#Override
protected Void doInBackground(Void... voids) {
long start=System.currentTimeMillis();
in=null;
try {
website=new URI(URL);
request.setURI(website);
} catch (URISyntaxException e) {
e.printStackTrace();
}
HttpPost httpPost=new HttpPost(URL);
List<NameValuePair>nameValuePairs=new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("name",name));
nameValuePairs.add(new BasicNameValuePair("pwd",pwd));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
response=httpClient.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
try {
in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
} catch (IOException e) {
e.printStackTrace();
}
try {
String line=in.readLine();
long end=System.currentTimeMillis();
long times=end-start;
String time=String.valueOf(times);
System.out.println(name);
System.out.println(NAME_PATTERN);
System.out.println(pwd);
System.out.println(PWD_PATTERN);
if (name.equals(NAME_PATTERN) && (pwd.equals(PWD_PATTERN))) {
bloggedIn=true;
System.out.println("Youre right");
}else
{
bloggedIn=false;
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void onPostExecute(String line, String time) {
if(bloggedIn=true){
navigateToMainActivity(time);
}else{ if (bloggedIn=false){
newp(line,time);
}
}
}
}
and this is the method called:
public void navigateToMainActivity(String timetoo) {
al=new AlertDialog.Builder(LoginActivity.this);
al.setTitle("Welcome");
al.setMessage("Hey there");
al.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
startActivity(new Intent(LoginActivity.this, Main.class));
}
});
al.show();
}
It looks like you need doInBackground to return true or false when it's finsished. You need doInBackground to return the boolean. Try this:
#Override
protected Boolean doInBackground(Void... arg0)
{
// your stuff
return bloggedIn; // instead of null or return the boolean where you are setting it true or false
}
Then your onPostExecute should look like this:
#Override
protected void onPostExecute(Boolean result)
{
super.onPostExecute(result);
if(result){
navigateToMainActivity(time);
}else{
newp(line,time);
}
}

Return a value from one activity to another

I want to display a message if the user types wrong password or username.
This is the class which takes the values
public class Login extends Activity {
Button submit_login;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
submit_login = (Button) findViewById(R.id.submit_login);
submit_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub.
EditText usr_number = (EditText) findViewById(R.id.username);
EditText password_main = (EditText) findViewById(R.id.password);
String username = usr_number.getText().toString();
String password = password_main.getText().toString();
String[] Loginvalues = {username,password};
new CheckUsername().execute(Loginvalues);
}
});
}
}
Now After new CheckUsername().execute(Loginvalues); this call i want to show a message in textview( id = loginStatus)
public class CheckUsername extends AsyncTask<String, Integer, String[]> {
HttpClient Client;
JSONObject json;
final static String URL = "someurl";
#Override
protected String[] doInBackground(String... params) {
// TODO Auto-generated method stub
String username = params[0].toString();
String password = params[1].toString();
Client = new DefaultHttpClient();
try {
json = ValidateUsername(username, password);
String status = json.getString("status");
if (status.equals("ok")) {
System.out.println(json.getString("response"));
JSONObject user_values = new JSONObject(json.getString("user"));
GlobalVariables newObj = new GlobalVariables();
newObj.setUserId(user_values.getString("id"));
newObj.setUserName(user_values.getString("name"));
System.out.println(newObj.getUserId());
System.out.println(newObj.getUserName());
} else {
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public JSONObject ValidateUsername(String username, String password)
throws ClientProtocolException, IOException, JSONException {
StringBuilder url = new StringBuilder(URL);
HttpPost post = new HttpPost(url.toString());
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("token", "ABCD"));
nameValuePairs.add(new BasicNameValuePair("func_name",
"validate_user"));
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = Client.execute(post);
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = response.getEntity();
String data = EntityUtils.toString(e);
JSONObject statusValue = new JSONObject(data);
return statusValue;
} else {
System.out.println(status);
return null;
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
status.equals("ok") this is the identifier which lets us know if logged or not
Thanks
It appears you might be misunderstanding the functionality of an AsyncTask, or just haven't read up on it too much. A big piece of clarification is that an AsyncTask is not an Activity. It is important to understand what an Activity is and how it is used to interact with the UI (it is one of a handful of classes that will let you do that).
Helping with your question, instead of having a separate class, just put your AsyncTask as a inner class of your main class.
public class Login extends Activity {
// Your code like onCreate and stuff
public class CheckUsername extends AsyncTask<String[], Void, String> {
// do your async task stuff
}
}
Extending on your AsyncTask, after you are done with do in background, you can return data to your class via onPostExecute()
public class CheckUsername extends AsyncTask<String[], Void, String> {
#Override
protected String doInBackground(String[]... params) {
//... do your stuff
return statusValue;
}
#Override
protected void onPostExecute(String statusValue) {
setText(statusValue);
}
}
In your main class, have a method like setText that will allow you to work with your return value as needed
public void setText(String return) {
if (return.equals("ok") { // or whatever it is supposed to equal if it's ok
// set your text to whatever, you are ok
}
else {
// set your text to whatever, bad password
}
}
In short, the design idea behind an AsyncTask is
public class AsyncTaskName extends AsyncTask<IN_PARAMETER, PROGRESS_PARAMETER, RETURN_PARAMETER> {
#Override
protected RETURN_PARAMETER doInBackground(IN_PARAMETER... params) {
// do your stuff
return (variable of type RETURN_PARAMETER);
}
#Override
protected void onProgressUpdate(PROGRESS_PARAMETER... progress) {
// do your stuff
}
#Override
protected void onPostExecute(RETURN_PARAMETER returnParam) {
// interact with your UI, like calling a method from your activity
}
}
It is worth noting that onProgressUpdate is often not needed for a task, unless you want to notify the user of the update progress of your AsyncTask directly.
AsyncTasks are meant to do operations off of the UI, but still be able to easily interact with it. The method doInBackground tells the AsyncTask that we want that done off of the UI thread, but onPostExecute tells us that we are done, close up our thread and return our data. Without onPostExecute you are floating dead in the water as far as UI interaction is concerned. You don't have to call a method from onPostExecute and can work with the UI directly (like textView.setText(returnValue);) but using a method makes it clearer that the work is being done by the Activity and not the AsyncTask itself.
you can use
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
}
It might solve your problem.

how to add runOnUiThread() in my Activity

I added the AsyncTask to offload network operations to a background thread.I need to make sure the UI operations are on the UI thread.So i want to Use runOnUiThread() in my Activity.
Thanks for your help
WifiApManager
public class WifiApManager {
private final WifiManager mWifiManager;
public WifiApManager(Context context) {
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
try {
if (enabled) { // disable WiFi in any case
mWifiManager.setWifiEnabled(false);
}
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return false;
}
}
public WIFI_AP_STATE getWifiApState() {
try {
Method method = mWifiManager.getClass().getMethod("getWifiApState");
int tmp = ((Integer)method.invoke(mWifiManager));
// Fix for Android 4
if (tmp > 10) {
tmp = tmp - 10;
}
return WIFI_AP_STATE.class.getEnumConstants()[tmp];
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
}
}
public boolean isWifiApEnabled() {
return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
}
public WifiConfiguration getWifiApConfiguration() {
try {
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
return (WifiConfiguration) method.invoke(mWifiManager);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return null;
}
}
public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
try {
Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
return (Boolean) method.invoke(mWifiManager, wifiConfig);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return false;
}
}
public ArrayList<ClientScanResult> getClientList(boolean onlyReachables) {
return getClientList(onlyReachables, 10);
}
public ArrayList<ClientScanResult> getClientList(boolean onlyReachables, int reachableTimeout) {
BufferedReader br = null;
ArrayList<ClientScanResult> result = null;
try {
result = new ArrayList<ClientScanResult>();
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if ((splitted != null) && (splitted.length >= 4)) {
// Basic sanity check
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);
if (!onlyReachables || isReachable) {
result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));
}
}
}
}
} catch (Exception e) {
Log.e(LOGTAG, e.toString());
} finally {
try {
br.close();
} catch (IOException e) {
Log.e(LOGTAG, e.toString());
}
}
return result;
}
}
connect.java
public class connect extends Activity{
WifiApManager wifiApManager;
TextView tv;
Button scan;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.connect);
tv =(TextView) findViewById(R.id.iptv);
new scan().execute();
}
public class scan extends AsyncTask<String, Integer, String> {
public Object WIFI_SERVICE;
#Override
protected void onProgressUpdate(Integer...integers) {
ArrayList<ClientScanResult> clients = wifiApManager.getClientList(false);
tv.setText("WifiApState: " + wifiApManager.getWifiApState() + "\n\n");
tv.append("Clients: \n");
for (ClientScanResult clientScanResult : clients) {
tv.append("####################\n");
tv.append("IpAddr: " + clientScanResult.getIpAddr() + "\n");
tv.append("Device: " + clientScanResult.getDevice() + "\n");
tv.append("HWAddr: " + clientScanResult.getHWAddr() + "\n");
tv.append("isReachable: " + clientScanResult.isReachable()+ "\n");
}
}
#Override
protected void onPostExecute(String result){
tv.setText(result);
}
#Override
protected String doInBackground(String... params) {
wifiApManager = new WifiApManager(this);
// the above line shows a Error
return null;
}
}
}
EDIT
I want to Display the processed text in a TextView
class scan extends AsyncTask<String, Void, Void> {
public Context context;
ArrayList<ClientScanResult> clients;
public scan(Context c) // constructor to take Context
{
context = c; // Initialize your Context variable
}
protected Void doInBackground(String... params) {
wifiApManager = new WifiApManager(context); // use the variable here
clients = wifiApManager.getClientList(false);
return null;
}
}
protected void onPostExecute(Void result){
ArrayList<ClientScanResult> clients;
tv.setText("WifiApState: " + wifiApManager.getWifiApState() + "\n\n");
tv.append("Clients: \n");
for (ClientScanResult clientScanResult : clients)//showin error in clients
{
tv.append("####################\n");
tv.append("IpAddr: " + clientScanResult.getIpAddr() + "\n");
tv.append("Device: " + clientScanResult.getDevice() + "\n");
tv.append("HWAddr: " + clientScanResult.getHWAddr() + "\n");
tv.append("isReachable: " + clientScanResult.isReachable()+ "\n");
}
}
}
I added the AsyncTask to offload network operations to a background thread.I need to make sure the UI operations are on the UI thread.So i want to Use runOnUiThread() in my Activity.
Ugh! No!!! Every method of AsyncTask runs on the UI Thread except for doInBackground(). So do your network operations in doInBackground() and update the UI in onPostExecute() or in onProgressUpdate() by calling publishProgress() from doInBackground().
Do not use runOnUiThread() with AsyncTask. There is no reason, at least known to me, to use that with AsyncTask since it has methods that already run on the UI Thread. I have never seen it do anything but cause trouble.
You can either call publishProgress() from your loop and update your TextView in onProgressUpdate() or add the values to an ArrayList and update in onProgressUpdate().
Please read the docs several times. AsyncTask is a bit tricky at first but once you learn what it does then it can be a beautiful thing.
Edit
Create an instance of your AsyncTask and pass your Activity Context to it
Scan myScan = new scan(this); // pass the context to the constructor
myScan.execute();
Then create a constructor in your AsyncTask and have it accept a Context.
public class scan extends AsyncTask<String, Integer, String>
{
public Object WIFI_SERVICE;
public Context context; // Context variable
public scan(Context c) // constructor to take Context
{
context = c; // intialize your Context variable
}
Now use that variable
#Override
protected String doInBackground(String... params)
{
wifiApManager = new WifiApManager(context); // use the variable here
return null;
}
Another Edit
class scan extends AsyncTask<String, Void, Void> {
ArrayList<ClientScanResult> clients;
Context context;
...
then initialize your `clients` in `doInBackground()`
clients = wifiApManager.getClientList(false);
change onPostExecute() to not accept anything
protected void onPostExecute(Void result){
and put your code that updates the TextView in there.
You should not be accessing any UI elements within doInBackground, This method runs in background thread. What you should do is override onPostExecute() method and access your TextView there. onPostExecute runs in UI thread, so you don't need to call runOnUiThread()

Android login not working

Hi Please Can someone help me look at this code? Don't know what am doing wrong,But the try block doesn't run. instead it goes to the catch block.
public void onClick(View arg0) {
//Toast.makeText(getBaseContext(), "connecting",Toast.LENGTH_SHORT).show();
// TODO Auto-generated method stub
httpclient = new DefaultHttpClient();
htpost = new HttpPost("http://10.0.2.2/fanaticmobile/log_in.php");
uname= username.getText().toString();
pass= password.getText().toString();
try {
namearray = new ArrayList<NameValuePair>();
namearray.add(new BasicNameValuePair("username", uname));
namearray.add(new BasicNameValuePair("password", pass));
htpost.setEntity(new UrlEncodedFormEntity(namearray));
response= httpclient.execute(htpost);
if(response.getStatusLine().getStatusCode()==200){
entity= response.getEntity();
if(entity != null){
InputStream stream = entity.getContent();
JSONObject jresponse = new JSONObject(ConvertInput(stream));
String logged= jresponse.getString("logged");
login_err.setText(""+logged);
if(logged.equals("true")){
Toast.makeText(getBaseContext(), "Successfull",Toast.LENGTH_SHORT).show();
//String retname= jresponse.getString("name");
//String retmail= jresponse.getString("email");
}else if(logged.equals("false")){
String message=jresponse.getString("message");
Toast.makeText(getBaseContext(), message,Toast.LENGTH_SHORT).show();
}
}
}else{
}
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), "Poor Connection",Toast.LENGTH_SHORT).show();
}
}//
This is the function to read the json object
private static String ConvertInput(InputStream is){
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line ="";
try {
while((line = reader.readLine())!= null){
sb.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
return sb.toString();
}// end of convert function
Please am new to this and i followed a tutorial to this point,but mine is not working. Have set permission(internet) in the manifest file
I have a suggestion Try to Use AsyncHttpclient for getting responses from server no need of this long codes.
http://loopj.com/android-async-http/
AsyncHttpClient asyncHttpClient=new AsyncHttpClient();
RequestParams params=new RequestParams();
params.put("username", uname);
params.put("password", pass);
asyncHttpClient.post("http://10.0.2.2/fanaticmobile/log_in.php", params,new AsyncHttpResponseHandler(){
#Override
public void onFailure(Throwable arg0, String arg1) {
// TODO Auto-generated method stub
super.onFailure(arg0, arg1);
}
#Override
public void onSuccess(String arg0) {
// TODO Auto-generated method stub
super.onSuccess(arg0);
}
});
Just include the jar file in your project it will be simple to use.
Like already been stated in the comments, you're running a network operation in your main thread (the UI thread). This is not only discouraged (lengthy operations should never use the Main Thread), but also forbidden in the case of networking.
response= httpclient.execute(htpost)
^ this fails.
Read how to move that code to an AsyncTask and do it the right way in the official google reference. Googling AsyncTask will help too.
A Pseudo Code version would be:
public class YourTask extends AsyncTask<Void, Void, Void>{
YourListener mListener;
public YourTask(final YourListener listener) {
mListener = listener;
}
#Override
protected Void doInBackground(final Void... params) {
// do your lengthy operation here
return null;
}
#Override
protected void onPostExecute(Void result) {
mListener.onVeryLongTaskDone();
}
public interface YourListener {
public void onVeryLongTaskDone();
}
}
Then make your activity implement that "YourListener" interface and the method onVeryLongTaskDone() will be called.
How do you start the task?
in your onClick method:
(new YourTask(YourActivityName.this)).execute();

How to stop the AsyncTask if the result of fetching data is null?

I want to cancel the asyncTask if my result string is null. ( I get a username and password from the user in a login activity and if this username and password don't exist in the database, the asyncTask has to cancel and ready to start the same task.) I read and applied something but they didn't run. Here is my AsyncTask :
class ProductConnect extends AsyncTask<Boolean, String, String> {
public AsyncResponse delegate=null;
private Activity activity;
public void MyAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(Boolean... params) {
String result = null;
StringBuilder sb = new StringBuilder();
try {
// http post
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet( "http://191.165.2.235/getProducts.php?login=1&user_name="+UserName+"&user_pass="+Password);
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != 200) {
Log.d("MyApp", "Server encountered an error");
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF8"));
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
if(reader.readLine() == null){
asyncTask.cancel(true);
}
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
if (isCancelled()) break;
}
result = sb.toString();
Log.d("test", result);
}
catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result) {
Intent passValue=new Intent(MainActivity.this, second.class);
try {
JSONArray jArray = new JSONArray(result);
JSONObject json_data;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
t = json_data.getString("name");
names.add(t);
latitude=json_data.getString("lat");
lats.add(latitude);
longtitude=json_data.getString("lon");
longts.add(longtitude);
}
passValue.putStringArrayListExtra("latitudes", (ArrayList<String>) lats);
passValue.putStringArrayListExtra("veri", (ArrayList<String>) names);
passValue.putStringArrayListExtra("longtitudes", (ArrayList<String>) longts);
startActivity(passValue);
} catch (JSONException e1) {
e1.printStackTrace();
} catch (ParseException e1) {
e1.printStackTrace();
}
super.onPostExecute(result);
}
protected void onPreExecute() {
super.onPreExecute();
ProgressDialog pd = new ProgressDialog(MainActivity.this);
pd.setTitle("Lütfen Bekleyiniz");
pd.setMessage("Authenticating..");
pd.show();
}
}
How should i follow a way ? Which methods should i use?
You are missing logic here, you should only call Async task if your data is not null.
Like this
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
EditText username=(EditText)findViewById(R.id.editText2);
String UserName=username.getText().toString().trim();
EditText password=(EditText)findViewById(R.id.editText1);
String Password=password.getText().toString().trim();
if (UserName.length()>0&& Password.length()>0) {
asyncTask.execute(true); }
}
});
AsyncTask is mainly using for operations which we wants to do in background thread, like webservice call. In this scenario, you are using AsyncTask for saving username and password through webservice. So before executing AsyncTask you must validate and have a null-check for both edit-texts for username and password. If everything is fine and get the password according to the defined password policy, just invoke the AsyncTask with these two values for httppost.
I notice this old post does not have the answer. So I will post this, hopefully it will help others.
To cancel a task simply call cancel()
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Parameters
mayInterruptIfRunning true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete.
Returns
false if the task could not be cancelled, typically because it has already completed normally; true otherwise
So in your case:
result = sb.toString();
if(result==null){
this.cancel(true);
}
Log.d("test", result);
to cancel outside of the task:
myTask.cancel(true);
You can use isCancel() to check , it returns true if this task was cancelled before it completed normally.
Additonally you can override asynctask method onCancelled() to take action when it's cancelled.
#Override
protected void onCancelled() {
}

Categories