Android:通过通知重新启动Activity时保留HttpClient和AsyncTask

时间:2014-03-25 15:52:23

标签: android android-notifications androidhttpclient

我有一个Android应用程序,使用HttpClient将文件上传到我的webservice。该应用程序具有在文件上传时更新的通知,并允许用户最小化应用程序并在后台执行其他操作。当我点击通知和活动重新启动时,我遇到了问题。我的HttpClient连接包含带有网络服务器会话信息的cookie,当通过录制通知重新启动活动时,此连接将丢失。看起来正在进行上传的旧片段在重启时被破坏(我知道这是因为我看到asynctask在重新启动时正常停止)。我试图使用一个保留的片段,但是当应用程序重新启动时,尽管我将片段设置为保留,但无法找到片段。

所以我的问题是,如何重新启动一个活动并保留我的HttpClient连接和我的AsyncTask(在重新启动期间上传仍在进行的情况下我需要这个)?


构建通知(按照Android dev guide的建议)

Builder builder = new NotificationCompat.Builder( getActivity() );
builder.setSmallIcon( R.drawable.ic_stat_notify_upload );
builder.setContentTitle( "Uploads" );
builder.setContentText( "Uploading " + fileCount + " file(s)" );
builder.setProgress( fileCount, 0, false );
Intent notificationActionIntent = new Intent( getActivity(), UploaderActivity.class );
TaskStackBuilder stackBuilder = TaskStackBuilder.create( getActivity() );
stackBuilder.addParentStack( UploaderActivity.class );
stackBuilder.addNextIntent( notificationActionIntent );
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT );
builder.setContentIntent( notificationPendingIntent );

RetainFragment代码(UploadTask扩展AsyncTask和CasRestProxyClient扩展HttpClient)

public class RetainFragment extends Fragment {

    private CasRestProxyClient casClient;
    private UploadEftTask uploadTask;

    @Override
    public void onCreate ( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
        setRetainInstance( true );
    }
    public ICasRestProxyClient getCasClient() {
        return casClient;
    }

    public void setCasClient(ICasRestProxyClient casClient) {
        this.casClient = casClient;
    }

    public UploadEftTask getUploadTask() {
        return uploadTask;
    }

    public void setUploadTask(UploadEftTask uploadTask) {
        this.uploadTask = uploadTask;
    }

}

上传活动(减少到我认为相关的内容)

public class UploaderActivity extends Activity {

    private static final String RetainFragmentIdString = "RETAIN_FRAGMENT";
    private RetainFragment retainFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        LoggerConfigurator.configure();
        setContentView(R.layout.activity_uploader);

        FragmentManager fragMgr = getFragmentManager();
        Fragment dataFragment = fragMgr.findFragmentByTag( RetainFragmentIdString );
        if ( dataFragment != null && dataFragment instanceof RetainFragment ) {
            retainFragment = (RetainFragment)dataFragment;
            // Restore state here...
        } else {
            retainFragment = new RetainFragment();
            FragmentTransaction fragTrans = fragMgr.beginTransaction();
            fragTrans.add( retainFragment, RetainFragmentIdString );
            fragTrans.commit();
            // Show initial state here...
        }

    }

    @Override
    public void onDestroy ( ) {
        retainFragment.setCasClient( uploadFragment.getCasClient() );
        retainFragment.setUploadTask( uploadFragment.getUploadTask() );
        super.onDestroy();
    }

}

2 个答案:

答案 0 :(得分:0)

在这种情况下,我可能会使用IntentService而不是AsyncTask。有关如何设置的基础知识可以在android文档中找到here。使用IntentService的好处是,一旦启动它的Activity(或在你的情况下Fragment)被销毁,它就可以继续运行。您可以使用意图在ActivityFragmentIntentService之间进行通信,以便您可以通知其他组件IntentService的进度。

AsyncTask模型设置/转换非常简单。指向文档的链接将向您显示如何启动/停止服务。除此之外,因为服务在后台运行,所以AsyncTask中doInBackground中的任何内容都可以在Service实现中的任何有意义的地方进行。只需在您希望接收更新的组件中使用BroadcastReceiver

更新 - 服务与IntentService

android中有两种Service。正常Service在后​​台持续存在,独立于Activity,但在主线程和IntentService上运行,后者也在后台持续存在,但在单独的工作线程上运行。您可以在提供的链接中找到basic breakdown使用不同线程的不同方法。

为了澄清上述内容,我会使用IntentService,因为它能够运行主线程。这在执行I / O操作时至关重要,自API 3.0起就一直需要。 IntentService还允许更新回主线程,如使用Intent所述。有关两种Service see this post

的比较

答案 1 :(得分:0)

我最终通过使用实现BoundService接口(Android Dev Doc)的Messenger来实现我想要的目标。仅在此之后仍然会导致服务在应用程序关闭时自行销毁。阻止服务销毁并允许重新连接的关键是在致电startService()之前致电bindService()。这将使服务在后台运行,直到我的应用程序调用{​​{1}}(在我的情况下,当用户明确注销时)。

在UploaderActivity.onStart()方法中调用:

stopService()