Android - Function execute listener - android

Hey i don't know if that's the right way to do it but if it is how can i do it...
I have one abstact class with AsyncTask
public abstract class A{
A(){
new Task().execute();
}
public abstract void postAction();
private class Task extends AsyncTask<String, String, String>{
protected String doInBackground(String... args)
{
//smth
}
protected void onPostExecute(String file_url){
postAction();
}
}
}
After that i have class that extends A class and overrides it's postAction() method:
public class B extends A{
B(){
//smth
}
postAction(){
//some action
}
}
In my activity i have instance of B and i want to perform action when postAction is called... so i want function listener if possible and how can i do it
class C extends Activity{
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
//somethingggg happeiningggg
}
MyListener listener = new MyListener(){
onPostActionCalled()
{
//start another activity or smt :D
}
};
}
So i have class for json response(class A) and class B that extends it and overrides it's post method so i can do what i want for specific situation(expect different data or smth else nvm)
In my activity i want to perform action when class B's post method is called
I don't know if i need to do listener or handler idk at all....

Stefan is right, why complicate things?
See this real simple example of threading:
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyTask(new TaskListener() {
#Override
public void finished(boolean result) {
// back on main thread after task finishes
}
}).execute();
}
private interface TaskListener{
void finished(boolean result);
}
private class MyTask extends AsyncTask<Object, Integer, Boolean>{
private TaskListener mListener;
public MyTask(TaskListener mListener) {
super();
this.mListener = mListener;
}
#Override
protected Boolean doInBackground(Object... params) {
// long running background operation
return true;
}
#Override
protected void onPostExecute(Boolean result) {
mListener.finished(result);
super.onPostExecute(result);
}
}
}

Related

Passing variable from BackgroundTask to Tab

Im sending data to background task to be processed but want to get the data back into tab1. This has got me flummoxed.
This is created from my activity
BackgroundTask backgroundTaskLogin = new BackgroundTask(Tab1Activity.this);
backgroundTaskLogin.execute(task,username,password);
I can see the data I want in backgroundtask
protected void onPostExecute(String result)
{
}
But cant get it back into my tab activity.. Help...
You need to use Interface which returns the result to the activity back.
/*Create an interface*/
public interface OnTaskCompleted {
void onTaskCompleted(Integer result);
}
/*Assign the values to the callback functions in AsyncTask*/
public class PerformTask extends AsyncTask<Integer, Integer, Integer> {
private static int counter;
private OnTaskCompleted listener;
public PerformTask(OnTaskCompleted listener) {
this.listener = listener; //Initialising listener
}
#Override
protected void onPostExecute(Integer result) {
listener.onTaskCompleted(result); //Assigning values to the callback function
}
}
/*Implement the Interface in you activity*/
public class MainActivity extends Activity implements OnTaskCompleted {
#Override
public void onTaskCompleted(Integer result) {
// The result contains the data you need
}
}

Call AsyncTask from another class

In an existing app I have an activity with an inner class which extends AsyncTask, this looks like the following:
public class Activity_1 extends BaseActivity {
....
new async().execute();
...
public class asyncextends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... progress) { ... }
protected void onPreExecute() { ... }
protected void onPostExecute(String result) { ... }
}
}
Now, I need to call the same doInBackground-method from another activity, but the onPostExecute() of the this inner class operates on some local UI variables and hence it's not possible to use it from outside the clas.
Is there any way I can call this AsyncTask, and just override the onPostExecute andonPreExecute-method, or shall I create yet another inner-class in the other activity, do the same background thing (of course move it to common utility-class or something), etc...?
You can make a separate abstract package private class, extending AsyncTask and implementing doInBackground() method:
abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
#Override
final protected String doInBackground(Void... progress) {
// do stuff, common to both activities in here
}
}
And in your activities just inherit from MyAsyncTask (new class probably should be private, by the way), implementing onPostExecute() and onPreExecute() methods:
public class Activity_1 extends BaseActivity {
...
new Async1().execute();
...
private class Async1 extends MyAsyncTask {
#Override
protected void onPreExecute(){
// Activity 1 GUI stuff
}
#Override
protected void onPostExecute(String result) {
// Activity 1 GUI stuff
}
}
}
If onPreExecute and onPostExecute contain some common actions as well, you can apply the following pattern:
abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
public interface MyAsyncTaskListener {
void onPreExecuteConcluded();
void onPostExecuteConcluded(String result);
}
private MyAsyncTaskListener mListener;
final public void setListener(MyAsyncTaskListener listener) {
mListener = listener;
}
#Override
final protected String doInBackground(Void... progress) {
// do stuff, common to both activities in here
}
#Override
final protected void onPreExecute() {
// common stuff
...
if (mListener != null)
mListener.onPreExecuteConcluded();
}
#Override
final protected void onPostExecute(String result) {
// common stuff
...
if (mListener != null)
mListener.onPostExecuteConcluded(result);
}
}
and use it in your activity as following:
public class Activity_1 extends BaseActivity {
...
MyAsyncTask aTask = new MyAsyncTask();
aTask.setListener(new MyAsyncTask.MyAsyncTaskListener() {
#Override
void onPreExecuteConcluded() {
// gui stuff
}
#Override
void onPostExecuteConcluded(String result) {
// gui stuff
}
});
aTask.execute();
...
}
You can also have your Activity implement MyAsyncTaskListener as well:
public class Activity_1 extends BaseActivity implements MyAsyncTask.MyAsyncTaskListener {
#Override
void onPreExecuteConcluded() {
// gui stuff
}
#Override
void onPostExecuteConcluded(String result) {
// gui stuff
}
...
MyAsyncTask aTask = new MyAsyncTask();
aTask.setListener(this);
aTask.execute();
...
}
I wrote the code from the head, so it might contain errors, but it should illustrate the idea.
Its so simple just Simply build an object of main class and than call the inner class like this
OuterMainClass outer = new OuterMainClass();
outer.new InnerAsyncClass(param)
.execute();
this answer is too late to help you but hope it help others.
Thanks
1.Create a constructor of AsynckTask in ClassOne.
2.Crate object or ClassOne by new keyword.
3.Call Async Task by object
ClassOne{
class AsyncParmas extends AsyncTask {
public ADDloadGeofenceDetails() {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
}
}
Class ClassTwo{
ClassOne obj= new ClassOne ();
obj.new AsyncParmas ().execute();
}
}
GoodLuck Who were facing problem.
If we create one static method which is in one class and and will be execute in any class in doInBackground of AsyncTask we can easily update UI through same class and even in different class .

ActionBarSherlock change ProgressBar from external AsyncTask

I want to set ProgressVisibility(true) in an AsyncTask. Is the AsyncTask in the Main, all is fine.
public class GlanceActivity extends SherlockActivity implements ActionBar.OnNavigationListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//This has to be called before setContentView and you must use the
//class in com.actionbarsherlock.view and NOT android.view
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_glance);
}
public class TestTask extends AsyncTask<String, String, ArrayList<String>> {
#Override
public void onPreExecute() {
// Show IndeterminateProgressBar
setSupportProgressBarIndeterminateVisibility(true);
}
#Override
protected ArrayList<String> doInBackground(String... params) {
// Load some Data...
return null;
}
protected void onPostExecute(ArrayList<String> arg) {
// Hide IndeterminateProgressBar
setProgressBarIndeterminateVisibility(false);
}
}
}
But if I want to generate an Extra File for the AsyncTask, the setProgressBarIndeterminateVisibility is undefined for GroupPageTask...
How can I use this method in an seperate AsyncTask File?
GlanceActivity.java
public class GlanceActivity extends SherlockActivity implements ActionBar.OnNavigationListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//This has to be called before setContentView and you must use the
//class in com.actionbarsherlock.view and NOT android.view
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_glance);
}
}
GroupPageTask.java
public class GroupPageTask extends AsyncTask<String, String, ArrayList<String>> {
#Override
public void onPreExecute() {
// Show IndeterminateProgressBar
setSupportProgressBarIndeterminateVisibility(true);
}
#Override
protected ArrayList<String> doInBackground(String... params) {
// Load some Data...
return null;
}
protected void onPostExecute(ArrayList<String> arg) {
// Hide IndeterminateProgressBar
setProgressBarIndeterminateVisibility(false);
}
}
You could hand over the context during AsyncTask construction:
public class GroupPageTask extends AsyncTask<String, String, ArrayList<String>>
{
private Context context;
public AsyncTask(Context context)
{
this.context = context;
}
protected void onPreExecute()
{
((Activity) context).setProgressBarIndeterminateVisibility(true);
}
protected void onPostExecute(ArrayList<String> arg)
{
((Activity) context).setProgressBarIndeterminateVisibility(false);
}
}
Then create your AsyncTask with the new constructor from your activity:
GroupPageTask groupPageTask = new GroupPageTask(this);
With the Answer of Matt Handys, i found the right way...
GlanceActivity.java
public class GlanceActivity extends SherlockActivity implements ActionBar.OnNavigationListener {
public static Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
GroupPageTask groupPageTask = new GroupPageTask(getSherlock());
}
}
GroupPageTask.java
public class GroupPageTask extends AsyncTask<String, String, ArrayList<Mannschaft>> {
private ActionBarSherlock sherlock;
#Override
public void onPreExecute() {
// Show IndeterminateProgressBar
sherlock.setProgressBarIndeterminateVisibility(true);
}
protected void onPostExecute(ArrayList<Mannschaft> arg) {
sherlock.setProgressBarIndeterminateVisibility(false);
}
}

onPostExecute() can't use MainActivity elements

I have doInBackground(). after function I want to change some TextView on MainActivity.
but When I trigger the function on main activity I got NullPointerException on TextView line.
protected String doInBackground(Object... arguments) {
some code..
return result;
}
#Override
protected void onPostExecute(String result) {
if(result!=null)
new MainActivity().setScoreListUpdate(result);
}
MainActivity:
public void setScoreListUpdate(String settings)
{
String[] yeniscore = settings.split("\\|");
if(yeniscore.length > 1)
{
birinci.setText(yeniscore[1]); << NULLPOINTEREXC.
}
}
The reason this gives a NullPointerException is that you create a new instance of MainActivity instead of working on your existing one.
What you need to do is pass a reference to your Activity to the AsyncTask and then call your method on that reference.
So in your AsyncTask-class you will have a variable:
private MainActivity myMainActivity;
Add a constructor to your AsyncTask-class:
public MyAsyncTaskClassName( MainActivity activity ) {
myMainActivity = activity;
}
Then in onPostExecute you do:
myMainActivity.setScoreListUpdate(result);
Use
MainActivity.this.setScoreListUpdate(result);
instead of
new MainActivity().setScoreListUpdate(result);
in yout postExecute method.
Also, TextView called birinci should be a field in your MainActivity class, not just a variable in the onCreate method for example.
EDIT: It works like this in my program. Check out the differences.
public class DeviceSettingsStatsActivity extends ListActivity {
AsyncTask<Void, Integer, ListAdapter> task = null;
ListAdapter listAdapter = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
task = new ComputeTask().execute();
}
protected void viewComputeResult(ListAdapter result) {
setListAdapter(result);
}
private class ComputeTask extends AsyncTask<Void, Integer, ListAdapter> {
#Override
protected ListAdapter doInBackground(Void... params) {
// some stuff
}
#Override
protected void onPostExecute(ListAdapter result) {
DeviceSettingsStatsActivity.this.viewComputeResult(result);
}
}
}

Finish the calling activity when AsyncTask completes

My calling activity:
public class Hello extends Activity {
public void onCreate(Bundle savedInstanceState) {
MyTask mt = new MyTask(this);
mt.execute();
}
Now In MyTask (an external class):
public class MyTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
public MyTask(Context context) {
mContext = context;
}
//doinbackground, etc
protected void onPostExecute() {
mContext.finish();
}
Other things are working as expected if I remove mContext.finish() above.
But if I'm calling mContext.finish() , I'm getting an error: The method finish() is undefined for the type Context (Eclipse doesn't show finish() when I write mContext. so that suggests I'm using finish() wrongly.)
What do I need to do to finish the calling activity Hello after MyTask completes the task
((Activity)mContext).finish();
Would be the correct way to cast a Context to an Activity and call its finish() method. Not sure why you'd want to finish an Activity from an AsyncTask though
What you can try to do instead of calling context.finish(), why don't you do a callback interface like this:
public interface TaskCallback{
void done();
}
Then you implement this into your Activity
public Hello extends Activity implements TaskCallback{
.....BUNCH OF ACTIVITY CODE.....
public void onCreate(Bundle savedInstanceState) {
MyTask mt = new MyTask(this);
mt.execute();
}
public void done() {
finish();
}
}
And instead of having Context as a parameter you have TaskCallback
public class MyTask extends AsyncTask<Void, Void, Void> {
private TaskCallback mCallback;
public MyTask(TaskCallback callback) {
mCallback = callback;
}
//doinbackground, etc
protected void onPostExecute() {
mCallback.done();
}
There you go, it gives you more flexibility to custom each implementation.
I got the same situation, then I do as follows:
public class MyTask extends AsyncTask<Void, Void, Void> {
private Activity mActivity;
private Context mContext;
public MyTask(Activity activity) {
mActivity = activity;
mContext = mActivity.getApplicationContext();
}
//doinbackground, etc
protected void onPostExecute() {
mActivity.finish();
}
Hope it help :)
Define a method in your activity class like this:
public void FinishAfterAsyncTask()
{
this.finish();
}
And call this method from the OnPostExecute method of the AsynTask class.
You could create a new private AsyncTask extended from your public one.
In this private AsyncTask you have access to the Activity stuff and you can override the onPostExecute method to finish it.
Your truly AsyncTask
public class MyPublicAsyncTask extends AsyncTask<Void, Void, Void> {
Context context;
public GetHorariosAsyncTask(Context ctx){
context = ctx;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// prepare yourself for an async work
}
#Override
protected Void doInBackground(Void... params) {
// Do yout cool async stuff
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// you're finish, let's tell to user
}
}
Your Activity with private AsyncTask
public class MyActivity extends Activity {
Activity mAct;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mAct = this;
}
private class MyPrivateAsyncTask extends MyPublicAsyncTask {
public MyPrivateAsyncTask(Context ctx) {
super(ctx);
// TODO Auto-generated constructor stub
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// our async task is completed! let's take care of this activity
mAct.finish();
}
}
}
Can you try
this.finish()
Seems like its because of calling it using mContext that it says undefined.

Categories

Resources