Android AsyncTask problem - android

I have a string that I want to update using AsyncTask class
here is my code:
public class MainActivity extends Activity{
private String str = "oldString";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getString();
}
private void getString(){
new CustomTask().execute();
}
private class CustomTask extends AsyncTask<Void, Void, String>{
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.i("Lesson3", "doInBackground method");
str = "newString";
return "someString";
}
protected void onPostExecute(String s){
Log.i("Lesson3", "onPostExecute method");
}
}
onPostExecute method is not called, thats the problem??
Thanks

Answer is simple,
#Override
protected void onPostExecute(String s){
Log.i("Lesson3", "onPostExecute method");
}
You forgot your #Override the execute calls onPostExecute of the super class since it has not been overridden as yet.

public class MainActivity extends Activity {
private String str = "oldString";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getString();
}
private void getString() {
new CustomTask().execute();
}
private void postExecuteCallback() {
Log.i("Lesson3", "String after callback: " + str );
}
private class CustomTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.i("Lesson3", "doInBackground method");
str = "newString";
return "someString";
}
protected void onPostExecute(String s) {
Log.i("Lesson3", "onPostExecute method");
postExecuteCallback();
}
}
}

Why have you decided it doesn't run? Following code works just fine (fixed syntax errors in yours):
package com.stackoverflow;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
public class Test extends Activity {
private String str = "oldString";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getString();
}
private void getString() {
new CustomTask().execute();
}
private class CustomTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.i("Lesson3", "doInBackground method");
str = "newString";
return "someString";
}
protected void onPostExecute(String s) {
Log.i("Lesson3", "onPostExecute method");
}
}
}

How about having our own AsyncTask ?
Please have a look.
public abstract class CustomAsyncTask<Params, Progress, Result> {
private boolean isFinished = false;
private Result res;
protected void onPreExecute() {
}
protected void onPostExecute(Result result) {
}
protected void onProgressUpdate(Progress progress) {
}
protected abstract Result doInBackground(Params...params);
private void CheckAndUpdateUI()
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(isFinished)
{
onPostExecute(res);
}
else
CheckAndUpdateUI();
}
},500);
}
public void execute(final Params...params)
{
onPreExecute();
//
CheckAndUpdateUI();
isFinished = false;
//
new Thread(new Runnable() {
#Override
public void run() {
res = doInBackground(params);
isFinished = true;
}
}).start();
}
}

Related

AsyncTask Thread with Intent

I run loading screen which should show current status "scanning packages, etc" . So that my activity wouldn't freeze I must use thread, but then I can't update status (TextField). I tried using AsyncTask but that didn't helped me at all, still after running I see text field unchanged.
public class LoadingScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loadingscreen_layout);
try {
startLoadingScreen();
}catch (Exception e){
Log.e("Scanner","Scanner",e);
}
}
public void startLoadingScreen(){
try{
new Thread(new Runnable() {
#Override
public void run() {
new ScanningOperation().execute("Scanning");
//loadingScreen.setStatus("Scanning");
final PackageManager pm = getPackageManager();
//get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
//changeIntent();
//finish();
}
});
} catch (Exception e){
Log.e("Thread","Thread");
}
}
private class ScanningOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return params[0];
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
TextView txt = findViewById(R.id.statusView);
txt.setText(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}

Android, kill/remove Asynctask at it's onPostExecute()

I'm developing an app that when user clicks on a Button it executes an Asynctask that this class calls a method at it's onPostExecute method that calls another Asynctask! It works when user clicks once, but at the second time it crashes and says Cannot execute task: the task has already been executed (a task can be executed only once)
.
public class Test extends Activity {
A a;
B b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
a = new A();
a.execute();
}
});
}
class A extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
// doing st
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
runB();
a.cancel(true);
}
}
public void runB() {
b = new B();
b.execute();
}
class B extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
// doing st
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//doing st
b.cancel(true);
}
}
Use AsyncTask.Status for checking status of AsyncTask before calling AsyncTask.execute() method on Button onClick:
#Override
public void onClick(View arg0) {
if(a ==null){
a = new A();
a.execute();
}
}
And in onPostExecute of B class assign null to a :
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//doing st
b.cancel(true);
a=null;
}

Use asynctask to call a function in android

As below code shows I have a function named record() I want to call this function with asynctask but I do not know how to work with asynctask, record function takes long to do some tasks so I need to use asynktsak.
public class Record extends Activity {
MediaPlayer mp;
String name;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.record);
mp = new MediaPlayer();
record();
}
public void record() {
.
.
.
}
}
Try this-
public class Record extends Activity {
MediaPlayer mp;
String name;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.record);
mp = new MediaPlayer();
new Task1().execute();
}
class Task1 extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(Void... arg0)
{
//Record method
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
}
}
}
Make AsyncTask Class and write code there and call your AsyncTask Class by new AsyncTaskClass().execute();
Try below code for your reference.
public void record() {
new AsyncTask<Void, Void, Void() {
#Override
protected void doInBackground(Void... params) {
}
Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
}
}.execute();
}

how to make a asynctasc work and dismiss after sometime?

I have a asynctask and I want to make it to be canceled after some time, 60 sec for example.
I think I have to it inside a while statemant, but I dont know how to count the time.
Here is my idea:
public class ThreadWithAutoCancel extends AsyncTask<Void, Void, Void> {
public ThreadWithAutoCancel(int timeOut) {
WatchDog watchDog = new WatchDog(this);
watchDog.execute(timeOut);
}
#Override
protected Void doInBackground(Void... params) {
// Do the job
return null;
}
class WatchDog extends AsyncTask<Integer,Void,Void>{
private long startTime;
private AsyncTask task;
public WatchDog(AsyncTask taskToStop){
task = taskToStop;
}
#Override
protected void onPreExecute(){
startTime = System.currentTimeMillis()/1000;
}
#Override
protected Void doInBackground(Integer... params) {
while(System.currentTimeMillis()/1000 < startTime+params[0]){
}
task.cancel(true);
return null;
}
}
}
After starting the AsyncTask, hold a reference to it and call cancel on it 60 seconds later, perhaps on a UI Thread Handler. Inside your doInBackground method you will have to make sure you return if isCancelled returns true. I hope the following snippet will help:
public class MyActivity extends Activity {
private Handler mHandler;
private AsyncTask<?, ?, ?> mTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
}
#Override
protected void onPostResume() {
super.onPostResume();
mTask = new MyCustomTask();
mTask.execute(1, 2, 3);
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mTask.cancel();
}, 60L);
}
}
And inside your custom task:
public class MyCustomTask extends AsyncTask<Integer, Float, String> {
#Override
protected String doInBackground(Integer... params) {
String output = "";
for (Integer i : params) {
// Check status for each param
if (isCancelled()) {
return output;
}
...
}
}
#Override
protected void onCancelled(String result) {
// This bit runs on the UI thread
...
}
You can do this using handler. For example this code will show "Completed" on TextView with R.id.mytext after asynctask will execute for 60 seconds:
final int FINISH = 1;
Thread waitingThread;
MyAsyncTask myAsyncTask;
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == FINISH)
{
myAsyncTask.cancel(true);
((TextView) findViewById(R.id.mytext)).setText("Completed");
}
};
};
// ...
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
waitingThread = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(60);
mHandler.sendEmptyMessage(FINISH);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
waitingThread.start();
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
while (true) {
// do something
}
}
}

Json Element returns null in AsyncTask

When I call only wpCategories = JsonToElement.getllAllCategory(); in the buttons onClick methood it works fine. (wpCategories get filled with data). But when I put this in a asynctask, wpCategories returns null. (is the doInBackground not being called?)
Here is my buttons on click methood:
public void onImageGridClick(View view) {
new GetJsonElementTask().execute();
Intent intent = new Intent(this, CategoryGridActivity.class);
intent.putParcelableArrayListExtra(Extra.IMAGES, wpCategories);
startActivity(intent);
}
And the asyncTask:
private class GetJsonElementTask extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(HomeActivity.this, "",
"Loading...");
}
#Override
protected String doInBackground(Void... arg0) {
wpCategories = JsonToElement.getllAllCategory();
return null;
}
#Override
protected void onPostExecute(String value) {
progressDialog.dismiss();
}
#Override
protected void onProgressUpdate(Integer... progress) {
Log.v("DEBUG_LOG", "In onProgressUpdate");
}
}
Start your Activity inside onPostExecute because this method execute after doInBackground execution complete :
#Override
protected String doInBackground(Void... arg0) {
wpCategories = JsonToElement.getllAllCategory();
return wpCategories; //<<< return value from here
}
#Override
protected void onPostExecute(String value) {
progressDialog.dismiss();
Intent intent = new Intent(this, CategoryGridActivity.class);
intent.putParcelableArrayListExtra(Extra.IMAGES, value);
startActivity(intent);
}
Try following
public void onImageGridClick(View view) {
new GetJsonElementTask().execute();
}
public void startCategoryGridActivity(){
Intent intent = new Intent(this, CategoryGridActivity.class);
intent.putParcelableArrayListExtra(Extra.IMAGES, wpCategories);
startActivity(intent);
}
And the asyncTask:
private class GetJsonElementTask extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(HomeActivity.this, "",
"Loading...");
}
#Override
protected String doInBackground(Void... arg0) {
wpCategories = JsonToElement.getllAllCategory();
return null;
}
#Override
protected void onPostExecute(String value) {
progressDialog.dismiss();
startCategoryGridActivity();
}
#Override
protected void onProgressUpdate(Integer... progress) {
Log.v("DEBUG_LOG", "In onProgressUpdate");
}
}

Categories

Resources