从一个 activity 启动 AsyncTask,在另一个中获取结果

start AsyncTask from one activity, get result in another

我是 Android 编程新手,我想创建一个中央数据库服务 class 来处理与外部数据库的用户数据交换。为此,我创建了一个在成功登录后启动的服务。我创建了另一个 class 扩展 AsyncTask 来进行数据检索。 现在,我希望将数据检索方法存储在服务中。我会从不同的活动中激发对服务的意图,并且使用 .setAction() 我会确定调用哪个方法,或者检索哪个数据。

我还创建了一个接口 class 来处理 AsyncTask 结果。 现在,从 this question 开始,我认为可以让多个侦听器接收同一个 AsyncTask 结果。但现在这似乎无法实现:我想在 MainMenuActivity 中检索 AsyncTask 结果,但我无法在那里创建 AsyncUserData 的实例作为 UserData class 的委托。在我下面的示例中,缺少的部分是要使用的 UserData class 的 AsyncUserData 的有效实例。我该怎么做?

示例如下: MainMenuActivity

public class MainMenuActivity extends ActionBarActivity implements AsyncUserData {
  TextView tvUsername;

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_menu);
    tvUsername =
      (TextView) findViewById(R.id.tvUsername);
    TelephonyManager tManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    String uid = tManager.getDeviceId();
    getDataFromUserSessionService(this, uid);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main_menu, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override
  public void retrieveResult(String result) throws JSONException {
    JSONObject jsonObject = new JSONObject(result);
    String joName;
    joName = jsonObject.getJSONObject("name").toString();
    user.setName(joName);
    tvUsername.setText(joName);
  }

  public void getDataFromUserSessionService(Context context, String uid) {
    Intent intent = new Intent(context, UserSession.class);
    intent.setAction(UserSession.ACTION_FETCH_USER_DATA);
    intent.putExtra(UserSession.UID, uid);
    context.startService(intent);
  }

UserSession 服务

public class UserSession extends IntentService {
  public static final String ACTION_FETCH_USER_DATA = "com.example.blahblah.services.action.read_user_data";

  @Override
  protected void onHandleIntent(Intent intent) {
    if (intent != null) {
      utils = new Utils(this);
      final String action = intent.getAction();
      uid = intent.getStringExtra(UID);
      if (ACTION_FETCH_USER_DATA.equals(action)) {
        handleUserDataFetch(uid);
      }
    }
  }

  private void handleUserDataFetch(String uid) {
    String[] parameters = new String[2];
    parameters[0] = uid;
    parameters[1] = Constants.USER_DATA_FETCH;
    UserData userData = new UserData(this);
    userData.execute(parameters);
  }

UserData AsyncTask Class(Utils class 还有一个 post 方法):

public class UserData extends AsyncTask < String, Void, String > {
  public AsyncUserData delegate = null;
  private Context myContext;

  public UserData(Context context) {
    myContext = context;
  }

  @Override
  protected String doInBackground(String...params) {
    String serverResponse = "";
    String uid = params[0];
    Utils utils = new Utils(myContext);
    String phpName = params[1];
    List < NameValuePair > nameValuePairs = new ArrayList < NameValuePair > ();
    nameValuePairs.add(new BasicNameValuePair("uid", uid));

    try {

      serverResponse = utils.passDataToServer(phpName, nameValuePairs);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return serverResponse;
  }

  protected void onPostExecute(String result) {
    try {
      delegate.retrieveResult(result);
    } catch (JSONException e) {
      e.printStackTrace();
    }
  }

};

AsyncUserData接口:

public interface AsyncUserData {
  void retrieveResult(String result) throws JSONException;
}

听起来您可能想要使用事件总线,例如 otto

您可以使用存储对 activity

的引用的单例
    public class ServiceToActivity
    {

                public ActionBarActivity mainactivity = null;
                private static ServiceToActivity singleton = null;
                public Class<?> cl = null;

                private ServiceToActivity()
                {

                }

                public static ActionBarActivity getSingleton()
                {
                    if(singleton==null)
                           return null;
                    return singleton.mainactivity;
                }

               public static Class<?> getSingletonClass()
                {
                    if(singleton==null)
                           return null;
                    return singleton.cl;
                }

                public static void setSingleton(ActionBarActivity mainactivity, Class<?> cl)
                {
                      if(singleton==null)
                             singleton = new ServiceToActivity();
                      singleton.mainactivity = mainactivity;
                      singleton.cl = cl;
                }
    }

然后在服务启动前创建单例

  public void getDataFromUserSessionService(Context context, String uid) {
Intent intent = new Intent(context, UserSession.class);
intent.setAction(UserSession.ACTION_FETCH_USER_DATA);
intent.putExtra(UserSession.UID, uid);
ServiceToActivity.setSingleton(this,this.getClass());   //create Singleton to store a reference to the activity
context.startService(intent);
}

在UserData中检索数据到主activity by:

 protected void onPostExecute(String result) {
try {
  Class<?> cl = ServiceToActivity.getSingletonClass();
  Method met = cl.getMethod("retrieveResult", String); //String because result is of type String: you can use result.getClass() instead
  met.invoke(cl.cast(ServiceToActivity.getSingleton()), result); // compare it to this ServiceToActivity.getSingleton().retrieveResult(result);
} catch (JSONException e) {
  e.printStackTrace();
}
}