I have one class that extends Asynctask. In this class I have a method that returns a hash map. How can I get this Hashmap in different class that extends Activity.
Anyone give me some reference code?
You can create a listener in your Activity, then pass this listener into your AsyncTask. Once the AsyncTask completes you can call the listener to set the Hashmap. So in your AsyncTask create your listener:
public static interface MyListener {
void setHashmap(Hashmap myHashmap);
}
Also, have a function to set your listener:
public void setListener(MyListener listener) {
this.listener = listener;
}
Then in onPostExecute call the function on your listener
listener.setHashmap(myHashmap);
In your activity implement this listener:
public class MyActivity extends Activity implements MyListener { ...
public void setHashmap(Hashmap hashmap) {
// do stuff here
this.hash = hashmap
}
Then finally set your listener and start your AsyncTask:
AsyncTask task = new MyAsyncTask();
task.setListener(this);
task.execute();
Of course you could also just put your AsyncTask in your Activity then you can set the hashmap in onPostExecute.
Related
I'm having trouble implementing a delegate in my android app.
In my GetData class I have nested asynctask, and I need to notify my main activity when all the work has actually finished.
I came up with this answer from Mohd Mufiz
What is the best way for AsyncTask to notify parent Activity about completion?
But I always get stuck at the same point:
in my GetData class I call a constructor with the delegate as only argument:
public class GetData {
private TaskDelegate delegate;
public GetData(TaskDelegate delegate) {
this.delegate = delegate;
}
...
}
In my main activity I don't know what I have to pass to get it working:
GetData getData = new GetData(**???**);
Going from the question you linked to, that defined TaskDelegate as :
public interface TaskDelegate {
public void taskCompletionResult(String result);
}
You can pass GetData any instance of a class that implements TaskDelegate - but typically, that would be the object that creates it - ie. your main activity (and so, therefore, it would also implement "void taskCompletionResult(String result);"). That then means you can pass "this" to GetData's constructor, so :
public class MyMainActivity implements TaskDelegate {
public void someMethod() {
GetData getData = new GetData(this);
}
public void taskCompletionResult(String result) {
// do stuff
}
}
I am starting an AsyncTask from an Activity. When, the AsyncTask completes its execution I need to send a broadcast which needs to call Activity method to update the UI.
Any good approach to achieve this.
Yes.
If the AsyncTask is an inner class of your Activity then it has access to any member variables and your Activity methods. If it isn't then you can simply pass variables to its constructor or even a reference to the Activity to call Activity methods from onPostExecute(). Without any code its hard to say much else.
To pass an instance of your Activity and use its methods if its a separate class then you can create a constructor and do something like
public class MyTask extends AsyncTask<...> // add your params
{
private MyActivity activty;
public MyTask (MyActivity act)
{
this.activty = activty;
}
// ...
}
and in onPostExecute() add something like
activity.myMethod();
and call the task like
MyTask task = new MyTask(this); // pass a reference of the activity
task.execute(); // add params if needed
If the AsyncTask is a separate file from the Activity then you can see this answer on how to use an interface for a callback
Please use Interface.
interface INotifyChange {
void notifyChange(); // You can use params to transfer data :D
}
In Activity you should implements this interface.
YourActivity extends Activity implements INotifyChange {
#Override
public void notifyChange() {
// Right here, you can Update UI.
}
}
When you create new instance of AsyncTask
Example:
YourAsyncTask mTask = new YourAsyncTask(this); // You put INotifyChange
In YourAsyncTask
private INotifyChange iNotifyChange;
public YourAsyncTask(INotifyChange iNotifyChange) {
this.iNotifyChange = iNotifyChange;
}
// When you complete doInBackground or anywhere you want to Update UI please use iNotifyChange.notifyChange()
Example:
#Override
public void onPostExecute(ResultType mResult) {
iNotifyChange.notifyChange();
}
By this way I often use to update progress bar. In this case, I use parameter in my method:
Example:
iNotifyChange.notify(progress);
Have you considered overwriting the onPostExecute() method of the AsyncTask to update the UI? Try something like this:
AsyncTask<String, Void, Bitmap> task = new AsyncTask<String, Void, Bitmap>(imageView)
{
private ImageView imageView;
public AsyncTask(ImageView imageView)
{
this.imageView = imageView;
}
#Override
protected Bitmap doInBackground (String... params)
{
if(params.length > 0)
{
String filePath = params[0];
// Load Bitmap from file
return bitmap;
}
}
#Override
protected void onPostExecute(Bitmap result)
{
imageView.setImageBitmap(result);
}
}
task.execute(filePath);
I would like to call an Activity method after the onPostExecute of my AsyncTask.
Do you know how I can do that?
I want to call in the sendSMS(String phoneNumber, String message) method in the onPostExecute.
One way is to pass an instance of the Activity through PostTask constructor, something like:
private class PostTask extends AsyncTask<String, Integer, String>
{
private AsyncBigCalculActivity activity;
public PostTask(AsyncBigCalculActivity activity)
{
this.activity = activity;
}
// ...
}
and on creating the PostTask instance, pass the activity instance:
new PostTask(this).execute();
Now you can invoke sendSMS() from within PostTask, like:
activty.sendSMS(...);
Also note that if you are defining the PostTask as a private class inside the activty, then you can invoke sendSMS() like:
AsyncBigCalculActivity.this.sendSMS(...);
Add a constructor and a global variable to your AsyncTask like this:
AsyncBigCalculActivity mActivity;
public PostTask(AsyncBigCalculActivity a) {
mActivity = a;
}
Then simply use mActivity.sendSMS("test", "test") when you need it.
However, you should really have methods like sendSMS() in a utility class.
If your AsyncTask is an inner class of your Activity then you should be able to call the Activity method from your onPostExecute(). Otherwise, you can send the Context to a constructor of your AsyncTask and uses that to call the method
Write a Callback
You can create a CallBack using an interface. This way you can use your AsyncTask with any activity. (Loosely coupled code)
1) Create a Callback
interface MyAsyncTaskCallBack{
public void doStuff(String arg1,String arg2);
}
2) Initialize the callback in your AsyncTask
private class MyTask extends AsyncTask<String, Void, Void>
{
private MyAsyncTaskCallBackactivity callback;
public MyTask(MyAsyncTaskCallBackactivity callback)
{
this.callback = callback;
}
//Call callback.doStuff(....phonenum, ....message); in your postExecute
}
3) Implement the Callback in your Activity and override doStuff() method
public YourActivity extends AppCompatActivity implements MyAsyncTaskCallBack{
// Your Activity code
// new MyTask(this).execute("phonenum","msg"); //<--- This is how you run AsyncTask
private void sendMessage(String num, String msg){
// send msg logic
}
#Override
public void doStuff(String arg1,String arg2){
sendMessage(arg1,arg2); // invoke activity method
}
}
I am developing an application in which i need to send the value of the asynctask's onPostExecute method's result in to the previous activity , ie the activity in which the aync task is being called.pls put some codes. Anyhelp is appreciated
Two ways:
Declare class extending AsyncTask as private class in parent Activity
Pass Handler or Activity itself as param of class extending AsyncTask
If I were you, I'd follow the first option.
Look at DOCS:
class MyActivitySubclass extends Activity {
function runOnPostExecute(){
// whatever
}
private class MyTask extends AsyncTask<Void, Void, Void> {
void doInBackground(Void... params){
// do your background stuff
}
void onPostExecute(Void... result){
runOnPostExecute();
}
}
}
Note 1
Code placed in body of function onPostExecute is already run on Activity thread, you should just mention that this keywords leads to MyTask.this and not MyActivitySubclass.this
Well if your AsyncTask is an inner class, you could simply call a method in your activity from onPostExecute():
public class MyActivity extends Activity {
public void someMethod(String someParam) {
// do something with string here
}
public class InnerTask extends AsyncTask<...> {
protected void onPostExecute(result) {
someMethod(Send parameters);
}
}
}
The onPostExecute method is fired on the main UI thread, so anything done there is already on the AsyncTasks caller.
http://developer.android.com/reference/android/os/AsyncTask.html
Fire an event in the OnPostExecute.
Its an add on to the answer by Marek Sebera, he pointed to use a handler. To keep the code simple and intuitive use an interface. This isn't alien concept, we use it all the time for callback functions (eg: OnClickListner etc..). The code would look some thing like this.
public class InnerTask extends AsyncTask<...>
{
interface ResultHandler
{
void gotResult(<> result);
}
private ResultHandler myResult;
//constructor
public InnerTask(....params...,ResultHandler callback)
{
...
this.myResult = callback;
}
protected void onPostExecute(<>result)
{
...
myResult.gotResult(result);
}
}
public class MyActivity extends Activity implements InnerTask.ResultHandler
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
//do something
//if you want the InnerTask to execute here
InnerTask i = new InnerTask(....params...,this); //send 'this' as parameter
i.execute();
}
#Override
public void gotResult(<> result)
{
//from onPostExecute
}
}
If we want to use the same AsynTask class at multiple sites we can use this type of implementation instead of using nested classes implementation.
I'm not sure why it is but I cannot call a method in my asynctask that is not static.
protected void onPostExecute(String result) {
List<SingleEvent> thelist = PhotosActivity.parseJSONResponse(result);
PhotosActivity.refreshListView(thelist);
}
The method in my activity:
public void refreshListView(List<SingleEvent> theList){//method that adds the List to the ListView after asyncTask is finished.
SingleEventAdapter adapter = new SingleEventAdapter(this, theList);
this.list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
It says I should make my method static, but in doing so the code inside gets errors saying it cannot be used with static.
EDIT:
The following is my asynctask class:
public class CallWebServiceTask extends AsyncTask<String, Object, String> {}
it's not static?
You must do this (make sure your AsyncTask class is not static):
PhotosActivity.this.refreshListView(thelist);