I am calling Asynctask and after complition of doInBackground(String... arg0) i want to call onResume() in onPostExecute() Method.
You should not call explicitly activity lifecycle methods, they usually call base class versions - ie. super.onResume(), so you might mess with activity state. Instead move related code from onResume to some outer function, and call this function instead in your onPostExecute.
Afte AsyncTask Complete
put this line in onPostExecute()
notifyDataSetChanged();
This Will call onResume() Automaticly
or if this is not Work then call Dialog box.
when Dialog box open Activity gosein onPause()
and when DialogBox is close it will call onResume()
this will work
Simply call Activity.this.onResume(); on your postexecution method
1.First of you need to take reference of your Activity say MainActivity in your asynkTask class by doing this.
MainActivity activity=(MainActivity)context.
context is the variable that you pass during calling the asynktask class from your activity.
2.now you can call easily by doing this.
activity.onResume().
Why do you need to do that?
if your async task is a nested class just call a method directly.
public MainActivity extends Activity{
//all the usual functionalities
public void methodAfterAsyncTask(){
//do stuff here
}
private CustomAsyncTask extends AsyncTask<Void,Void,Void>{
#Override
public onPostExecute(){
super.onPostExecute();
methodAfterAsyncTask();
}
}
}
If you are a strong believer of OOP and like clean code :)..I use this method
MainActivity .java
public MainActivity extends Activity{
//all the usual functionalities
public void onResume(){
super.onResume();
new CustomAsyncTask(new AsyncListener(){
public void postTaskMethod(){
//do stuff here
}
}).execute();
}
}
AsyncListener.java
public interface AsyncListener{
void postTaskMethod();
}
CustomAsyncTask.java
publicCustomAsyncTask extends AsyncTask<Void,Void,Void>{
private AsyncListener listener;
public CustomAsyncTask(AsyncListener listener){
this.listener=listener;
}
#Override
public onPostExecute(){
super.onPostExecute();
if(null!=listener)
listener.postTaskMethod();
}
}
Related
I have a super-class called MainActivity and a secondary class called Insert.
The two class are defined as the code below.The Insert class extends the MainActivity class.
In the two class I have the onStop() method, and in the Insert class I have #Override. The problem is that when onStop is executed in the Insert class, also the onStop method of MainActivity is called. Why? How can I do?
Thank you!
public class MainActivity extends AppCompatActivity {
public void onStop() {
//some code
super.onStop();
}
}
public class Insert extends MainActivity {
#Override
public void onStop() {
//some code
super.onStop();
}
}
onStop is the default method provided by activity lifecycle. You can have your custom method name say onMyStop() and call that method from Insert class's onStop using super.onMyStop()
The reason is calling super.onStop() in Insert overriden method. But calling super.onStop is mandatory. To fix it, you can create another method like doOnStop in MainActivity, call it inside onStop of MainActivity and override in Insert without calling super.doOnStop.
Here is code sampe:
public class MainActivity extends AppCompatActivity {
public void onStop() {
super.onStop();
doOnStop();
//some code
}
public void doOnStop() {
}
}
public class Insert extends MainActivity {
#Override
public void doOnStop() {
//some code
}
}
I have a MainActivity, SecondaryActivity and an AsyncTask class.
MainActivity has a method called doSomething()
I call the AsyncTask from MainActivity like this:
new asyncTask(MainActivity.this).execute();
Which means I can reference the MainActivity in my onPostExecute
#Override
protected void onPostExecute(Boolean result){
super.onPostExecute(result);
# activity is defined as this.activity
activity.doSomething();
}
How can I call the AsyncTask from my SecondaryActivity in a similar manner, because I'd need a reference to my MainActivity to access its methods?
EDIT: I would want the doSomething() to be called at all times. So even if it's from SecondActivity, once it finishes its background operation -> doSomething()
The method I'm calling refreshes the screen of MainActivity to show data changes. Secondary activity only calls the AsyncTask when it is being paused/stopped/destroyed but currently the Asynctask finishes after MainActivity has started and so the changes aren't visible.
I think your AsyncTask in nested in the MainActivity currently. Its better you put it in separate class. Whatever parameter is required by it pass it in its constructor. Let both your activity implement the same interface. Something like this
class MainActivity/SecondaryActivity implements DoSomethingListener {
void doSomething() {
}
}
Also pass your activity reference to AsyncTask in the constructor.
Finally onPostExecute since you have reference to either MainActivity or Secondary Activity. Call activity.doSomething.
I guess you want to update something in MainActivity based on the result of the AsyncTask called from SecondaryActivity. In that case, I'd suggest calling SecondaryActivity with startActivityForResult. Then in your onPostExecute, call setResult to set a flag or some data.
Finally, in MainActivity override onActivityResult to call doSomething when the request code corresponds to SecondaryActivity.
So your requirement is to have a single instance of MainActivity. Data in MainActivity may be updated from within MainActivity or from SecondaryActivity. In either case the data to be updated is obtained using an AsyncTask.
My Suggestion
Add the following to the MainActivity in manifest, (More about android:launchMode here.)
android:launchMode="singleInstance"
When you are done interacting with SecondaryActivity, do this,
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("DATA1", "your_data1");
intent.putExtra("DATA2", "your_data2");
startActivity(intent);
finish();
Then in your MainActivity,
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String data1 = intent.getStringExtra("DATA1");
String data2 = intent.getStringExtra("DATA2");
}
Then call AsyncTask in MainActivity using data1 and data2.
NOTE: This is one way to approach your problem. There are other approaches such as startActivityForResult() depending on your requirement.
UPDATE
If you want to cancel your AsyncTask, call asyncTask.cancel(true);
However, this will not ensure your HttpRequest is aborted, as the cancel will take effect after the request has completed. The work-around for this is a bit hackish. After calling cancel(), contineously check if isCancelled() is true, then do httpRequest.abort() This will only be the fastest way to finish your async task. Need not necessarily mean the request gets aborted.
Try this in your UpsertTask class.
private Context mContext;
public UpsertTask(Context context){
mContext = context;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
if(mContext instanceof MainActivity){
((MainActivity) mContext).doSomething();
}
else if(mContext instanceof SecondActivity){
((SecondActivity) mContext).doSomethingElse();
}
}
#Override
protected void onPostExecute(Boolean result){
super.onPostExecute(result);
# activity is defined as this.activity
if (activity != null) {
if(activity instanceof MainActivity) {
activity.doSomething();
} else if(activity instanceof SecondaryActivity) {
activity.doSomethingElse();
}
}
}
I think that would work. (if you understand your question correctly).
One way this could be done is by using an event bus. This is a way of passing messages/data between activities. You can post to the bus and then activities can listen for the message if they register.
EventBus class (seperate)
public class EventBus extends Bus {
private static final EventBus bus = new EventBus();
public static Bus getInstance() { return bus; }
private EventBus() {}
}
MainActivity class
...
#Override
protected void onResume() {
super.onResume();
EventBus.getInstance().register(this);
}
#Override
protected void onPause() {
super.onPause();
EventBus.getInstance().unregister(this);
}
#Subscribe
public void asyncDone(String message) {
foo(message)
}
AsyncTask class
...
#Override
protected void onPostExecute(Boolean result){
super.onPostExecute(result);
EventBus.getInstance().post("My data")
Thanks to #theheartbreakpug from Reddit for giving me this solution.
I have an activity and a fragment. If I click a button then a fragment is called. Upon the result I got from the fragment I need some networking call to perform using volley. But I can't do any networking call from activity unless I call this within onClick() method.
I tried to perform networking from within onClick() of the fragment but that did not worked too.
How can i perform networking from the activity upon the result I got from the fragment? Do I must call from within onClick()?
This is the fragment
This is the Activity
I think that you can use callback.
Create intefrace and declare method saveResult() in it.
public interface YourInterface{
void saveResult();
}
After that your Activity must implement this interface and add your code for save result in database in saveResult method body
public class YourActivity implements YourInterface{
#override
void saveResult(){
//your code here
}
}
And finnaly in your fragment call method when you whant or when your fragment is ready.You can call method with help of
callBack.saveResult();
You must override onAttach in your fragment and there must initialize your callback
YourInterface callback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instanceof YourInterface ) {
callback = (YourInterface ) activity;
}
}
Try with other on click method in at your onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mark_distribution);
assign_buttton=(Button)findViewById(R.id.assign_marks);
view_buttton=(Button)findViewById(R.id.view_marks);
update_buttton=(Button)findViewById(R.id.update_marks);
//Like this-->>>
update_buttton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
marks_type=(String)assigned_marks_type.getText().toString();
marks=Integer.parseInt(assigned_marks.getText().toString().trim());
callback.saveResult(marks_type,marks);
}
});
//********************/
Intent i=getIntent();
course_title= i.getExtras().getString("COURSE_TITLE");
}
Hope to help you!
I have an issue where I need to access a method in my Activity from Android AsyncTask's onPostExecute() method
I have 2 Activities both contain a common method as below:
(1) Activity1 -- > refreshUI()
(2) Activity2 ----> refreshUI()
I got one AsyncTask call GetDataAsyncTask(Activity a ) which takes calling activity as argument
Now from my activity1 I will call new GetDataAsyncTask(Activity1.this).execute.
Same as above from my activity2 I will call new GetDataAsyncTask(Activity2.this).execute.
My AsyncTask is as below :
public class GetDataAsyncTask extends AsyncTask<String ,Void , String> {
public Activity context;
public PostAsyncTaskHelper(Activity c) {
context = c;
}
protected String doInBackground(String... arg0) {
// Webservice calls
}
protected void onPostExecute(String result) {
if(result.equals("qq")) {
//Where I am not able to access refreshUI()
//method of any one of my activities
context.refreshUI()
}
}
}
Can anyone help me how to get reference of any of the called activities from AsyncTask?
Make an interface that has the method refreshUI(), and make both Activity1 and Activity2 implement it. Then, you just need to typecast context to the type of the interface.
Also, you need to be careful about holding a reference to an Activity from inside an AsyncTask, because in the case of a config change (like screen rotation), you'll be holding on to a destroyed Activity instance. See here for details, and the corresponding example solution to this.
Define an interface for your Activities
public interface MyActivityRefreshInterface
{
public void refreshUI();
}
your Activities must be defined as implements MyActivityRefreshInterface.
Your onPostExecute can then cast the context as (MyActivityRefreshInterface)context
Because refreshUI is not a method in Activity. It is in your particular Acivity1 and Activity 2 classes, not the Activity class from Android. You should refactor so Activity1 and Activity2 to inherit from BaseActivity that has the refreshUI method on it and mark context in the AsyncTask as a BaseActivity
I start ASyncTask from the Activity:
public class PrepareRequestTokenActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new OAuthRequestTokenTask(this, consumer, provider).execute();
}
Then, depending on result of ASyncTask execution I should either close this PrepareRequestTokenActivity activity on not.
(Result is known to onPostExecute of AsyncTask)
onPostExecute you simple use your this variable to execute finish().
in your constructor keep your activity reference
and call finish() in onPostExcecute method
If you're working from within onPostExecute, and you're asyncTask() class is internal to your activity; simply calling MyClassName.this.finish() , or something alike, should work just fine? The onPostExecute(), I believe, has UI scope.