简体   繁体   English

从AsyncTask调用不同的活动方法

[英]Call different activity method from AsyncTask

I have a MainActivity , SecondaryActivity and an AsyncTask class. 我有一个MainActivitySecondaryActivity和一个AsyncTask类。
MainActivity has a method called doSomething() MainActivity有一个称为doSomething()的方法

I call the AsyncTask from MainActivity like this: 我这样从MainActivity调用AsyncTask:

new asyncTask(MainActivity.this).execute();

Which means I can reference the MainActivity in my onPostExecute 这意味着我可以在onPostExecute引用MainActivity

@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? 我需要以类似的方式从SecondaryActivity调用AsyncTask,因为我需要引用MainActivity来访问其方法?

EDIT: I would want the doSomething() to be called at all times. 编辑:我想一直在调用doSomething() So even if it's from SecondActivity, once it finishes its background operation -> doSomething() 因此,即使它来自SecondActivity,也要完成其后台操作-> doSomething()

The method I'm calling refreshes the screen of MainActivity to show data changes. 我正在调用的方法刷新MainActivity的屏幕以显示数据更改。 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. 辅助活动仅在被暂停/停止/销毁时才调用AsyncTask,但当前Asynctask在MainActivity启动后完成,因此更改不可见。

I think your AsyncTask in nested in the MainActivity currently. 我认为您的AsyncTask当前嵌套在MainActivity中。 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. 还将您的活动引用传递给构造函数中的AsyncTask。

Finally onPostExecute since you have reference to either MainActivity or Secondary Activity. 最后是onPostExecute,因为您可以引用MainActivity或Secondary Activity。 Call activity.doSomething. 调用activity.doSomething。

I guess you want to update something in MainActivity based on the result of the AsyncTask called from SecondaryActivity . 我猜您想根据从SecondaryActivity调用的AsyncTask的结果更新MainActivity的某些内容。 In that case, I'd suggest calling SecondaryActivity with startActivityForResult . 在那种情况下,我建议使用startActivityForResult调用SecondaryActivity Then in your onPostExecute , call setResult to set a flag or some data. 然后在您的onPostExecute ,调用setResult来设置标志或一些数据。

Finally, in MainActivity override onActivityResult to call doSomething when the request code corresponds to SecondaryActivity . 最后,在MainActivity ,当请求代码对应于SecondaryActivity时,重写onActivityResult以调用doSomething

So your requirement is to have a single instance of MainActivity. 因此,您的要求是拥有一个MainActivity实例。 Data in MainActivity may be updated from within MainActivity or from SecondaryActivity. MainActivity中的数据可以从MainActivity内部或从SecondaryActivity更新。 In either case the data to be updated is obtained using an AsyncTask. 无论哪种情况,要更新的数据都是使用AsyncTask获得的。

My Suggestion 我的建议

Add the following to the MainActivity in manifest, (More about android:launchMode here.) 将以下内容添加到清单的MainActivity中(有关android:launchMode的更多信息, 点击此处。)

android:launchMode="singleInstance"

When you are done interacting with SecondaryActivity, do this, 与SecondaryActivity交互完成后,请执行此操作,

Intent intent = new Intent(this, MainActivity.class);
    intent.putExtra("DATA1", "your_data1");
    intent.putExtra("DATA2", "your_data2");
    startActivity(intent);
    finish();

Then in your MainActivity, 然后在您的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. 然后使用data1和data2在MainActivity中调用AsyncTask。

NOTE: This is one way to approach your problem. 注意:这是解决您的问题的一种方法。 There are other approaches such as startActivityForResult() depending on your requirement. 根据您的要求,还有其他方法,例如startActivityForResult()。

UPDATE If you want to cancel your AsyncTask, call asyncTask.cancel(true); 更新如果要取消AsyncTask,请调用asyncTask.cancel(true); However, this will not ensure your HttpRequest is aborted, as the cancel will take effect after the request has completed. 但是,这不能确保您的HttpRequest中止,因为取消将在请求完成后生效。 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. 调用cancel()之后,连续检查isCancelled()是否为true,然后执行httpRequest.abort()这将是完成异步任务的最快方法。 Need not necessarily mean the request gets aborted. 不一定意味着请求被中止。

Try this in your UpsertTask class. 在您的UpsertTask类中尝试此操作。

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) EventBus类(单独)

public class EventBus extends Bus {
    private static final EventBus bus  = new EventBus();   
    public static Bus getInstance() { return bus; }    
    private EventBus() {}
}

MainActivity class MainActivity类

...
@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 AsyncTask类

...
@Override
protected void onPostExecute(Boolean result){
    super.onPostExecute(result);
    EventBus.getInstance().post("My data")

Thanks to @theheartbreakpug from Reddit for giving me this solution. 感谢Reddit的@theheartbreakpug给我这个解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM