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

Android:通过通知重新启动活动时保留HttpClient和AsyncTask,android,android-notifications,androidhttpclient,Android,Android Notifications,Androidhttpclient,我有一个Android应用程序,它使用HttpClient将文件上传到我的Web服务。该应用程序有一个在上传文件时更新的通知,允许用户最小化应用程序并在后台执行其他操作。当我点击通知并重新启动活动时出现问题。My HttpClient连接包含到Web服务器的带有会话信息的Cookie,当通过录制通知重新启动活动时,此连接将丢失。似乎在重新启动时,进行上传的旧片段被销毁了(我知道这一点,因为我看到在重新启动时asynctask会优雅地停止)。我曾尝试使用保留的片段,但当应用程序重新启动时,它无法定

我有一个Android应用程序,它使用HttpClient将文件上传到我的Web服务。该应用程序有一个在上传文件时更新的通知,允许用户最小化应用程序并在后台执行其他操作。当我点击通知并重新启动活动时出现问题。My HttpClient连接包含到Web服务器的带有会话信息的Cookie,当通过录制通知重新启动活动时,此连接将丢失。似乎在重新启动时,进行上传的旧片段被销毁了(我知道这一点,因为我看到在重新启动时asynctask会优雅地停止)。我曾尝试使用保留的片段,但当应用程序重新启动时,它无法定位片段,尽管我将片段设置为保留

因此,我的问题是,如何重新启动一个活动并同时保留HttpClient连接和AsyncTask(在重新启动期间仍在进行上载的情况下,我需要这样做)


生成通知(根据建议)

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

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


在这种情况下,我可能会在
AsyncTask
上使用
IntentService
。关于如何设置的基本知识可以在android文档中找到。使用
IntentService
的好处是,一旦启动它的
活动
(或者在您的情况下是
片段
)被销毁,它就可以继续运行。您可以使用意图在您的
活动
片段
意图服务
之间进行通信,以便通知
意图服务
的其他组件

AsyncTask
模型设置/转换非常简单。指向文档的链接将向您展示如何启动/停止服务。除此之外,由于服务在后台运行,因此无论您在
AsyncTask
的后台中拥有什么,都可以在
服务实现中有意义的地方使用。只需在您想要接收更新的组件中使用
广播接收器

更新-服务与意向服务

android中有两种
服务。一个正常的
服务
,它保持在后台,独立于
活动
,但在主线程上运行;一个
IntentService
,它也保持在后台,但在单独的工作线程上运行。您可以在提供的链接中找到使用独立线程的多种不同方法


为了澄清上述问题,我将使用
IntentService
,因为它能够从主线程运行。这在执行I/O操作时是至关重要的,自API 3.0以来就一直需要这样做
IntentService
还允许更新回主线程,如使用
Intent
所述。为了进一步比较这两种类型的
服务

,我最终通过使用实现
Messenger
接口的
BoundService
实现了我想要的功能()。在应用程序关闭时,仅此一步仍然会导致服务自我毁灭。防止服务破坏并允许重新连接的关键是在调用
bindService()
之前调用
startService()
。这将使服务在后台运行,直到我的应用程序调用
stopService()
(在我的情况下,当用户明确注销时)

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


请澄清回答中使用的是
IntentService
而不是
Service
。这有助于防止任务关闭。我看不到将httpclient传递给服务的方法(尽管序列化可能会有所帮助)、从服务返回客户端(当应用程序重新启动时,它将需要这样做)以及终止任务的能力(如果调用了取消或注销操作)。可以在服务中执行这些操作吗?可以-我不会将
HttpClient
传递给服务。相反,只需传递您将要上传的数据(或URI,如果存储在本地),然后初始化您的
HttpClient
HttpPost
或您需要的服务中的任何元素。因为服务有自己的上下文,很像一个活动,只是没有任何UI功能。
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 );
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();
    }

}
    Intent initService = new Intent( this, UploaderService.class );
    startService( initService );
    // serviceConnection is a member of UploaderActivity of type 
    // android.content.ServiceConnection that handles when the service binds.
    // This needs to be a class member to unbind() when the activity is destroyed
    bindService( initService, serviceConnection, Context.BIND_AUTO_CREATE );