【问题标题】:How to notify my main activity, that thread has finihed?如何通知我的主要活动,该线程已完成?
【发布时间】:2014-11-03 21:26:49
【问题描述】:

我需要做一些简单的事情:我必须从我的应用程序中制作一张照片,将其发送到服务器(在后台)并在发送后显示通知。一切正常,但现在我必须等待发送文件结束 - 之后相机活动将关闭。我不想等待,我想在拍照后立即回到我的主要活动(但上传仍会在线程中进行,并在完成时发送通知)。

问题:我不知道如何让我的主要活动知道,该线程已完成照片上传。 也许将上下文或处理程序传递给相机活动会有所帮助,但putExtra() 无法做到这一点。

有什么建议吗?

我的一些代码片段:

MainActivity.java:

Intent intent = new Intent(this, Camera.class);
startActivityForResult(intent, Constants.REQUESTCODE_CAMERA);

Camera.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    //(...)
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);    
    intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
    startActivityForResult(intent,TAKE_PHOTO);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //(...)
    new SendFileToServer().execute();
    // finish(); // I would like to finish Camera.java here, and get back to MainActivity, while SendFileToServer uploads file and send some notification later
}

protected class SendFileToServer extends AsyncTask<Void, Void, String>{

    @Override
    protected String doInBackground(Void... params){
        //(...) // here is sending of file to server, it works
    }

    @Override
    protected void onPostExecute(String result) {
        //(...) // code below doesn't work, because I didn't pass "context", I don't know how, or it's just impossible
        MainActivity mainActivity = (MainActivity) context;                 
        mainActivity.sendFileName(filename);
    }

}

【问题讨论】:

  • 请附上您的上传代码。您添加了 AsyncTask 标记,因此我假设您在 AsyncTask 中进行联网。您可以覆盖 AsyncTask 的 onPostExecute 方法,该方法在任务完成时被调用,并在 UI 线程上运行,因此您可以在那里进行任何视图更改。

标签: android multithreading android-intent android-activity android-asynctask


【解决方案1】:

你可以做的是在 AsyncTask 结束时发送一个广播,并在你想要做某事的活动中注册一个接收器(例如显示通知)。

为此,您需要:

1) 将 Application Context 传递给您的 AsyncTask(在 Activity 中):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //(...)
    new SendFileToServer(getApplicationContext()).execute(); // pass application context to AsyncTask
    finish();
}

2) 从 onPostExecute() 发送广播:

protected class SendFileToServer extends AsyncTask<Void, Void, String>{

    private Context context;

    public SendFileToServer(Context context) {
        this.context = context;
    }

    @Override
    protected String doInBackground(Void... params){
        //(...) // here is sending of file to server, it works
    }

    @Override
    protected void onPostExecute(String result) {
        Intent intent = new Intent("com.example.UPLOAD_FINISHED");
        context.sendBroadcast(intent);
    }
}

3) 在 MainActivity 中注册一个 BroadcastReceiver(不要忘记在 onPause() 中取消注册接收者):

MainActivity.class

private BroadcastReceiver broadcastReceiver;

@Override
protected void onResume() {
    super.onResume();
    IntentFilter intentFilter = new IntentFilter(
            "com.example.UPLOAD_FINISHED");
    broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // show notification
        }
    };
    registerReceiver(broadcastReceiver, intentFilter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(broadcastReceiver);
}

【讨论】:

  • 我不知道 BroadcastReceiver - 很好用,谢谢! :)
  • 尽管自发布此答案以来已经有很长时间了,但我对它投了反对票,因为一般来说,当前应用程序与其他应用程序之间存在某种通信时会使用 BroadcastReceivers,或者操作系统。请参考Android官方文档developer.android.com/guide/components/broadcasts
猜你喜欢
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多