我有一个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();
}
}
答案 0 :(得分:0)
在这种情况下,我可能会使用IntentService
而不是AsyncTask
。有关如何设置的基础知识可以在android文档中找到here。使用IntentService
的好处是,一旦启动它的Activity
(或在你的情况下Fragment
)被销毁,它就可以继续运行。您可以使用意图在Activity
或Fragment
与IntentService
之间进行通信,以便您可以通知其他组件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()