And*_*ord 18 android background-process android-lifecycle android-asynctask
我的Android 4+应用程序连接到自定义Web服务,该服务用于每隔几分钟同步一次数据.为了确保在线数据始终是最新的,我想在应用程序关闭/发送到后台时触发同步.
在iOS下这很容易:
applicationDidEnterBackground:在AppDelegate中收听beginBackgroundTaskWithName:开始您长时间运行的后台任务,并避免在任务仍在运行被暂停如何在Android上执行此操作?
第一个问题是,没有任何东西相当于applicationDidEnterBackground:.到目前为止我发现的所有解决方案都建议使用主要的Activities onPause()方法.但是,这会在主要Activity暂停时调用,这也是Activity在应用程序中启动另一个时的情况.接口的onActivityPaused()方法是正确的ActivityLifecycleCallbacks.
那么,如何检测应用程序(不只是一个Activity)是关闭还是发送到后台?
第二个问题是,我没有找到任何关于如何运行后台任务的信息.所有解决方案都指向简单的启动AsyncTask,但这真的是正确的解决方案吗?
AsyncTask将启动一项新任务,但当应用程序关闭/不活动时,此任务是否也会运行?我需要做什么,以防止应用程序和任务在几秒钟后被暂停?在应用程序完全暂停之前,如何确保任务可以完成?
Anj*_*ali 17
以下代码可帮助您在应用关闭或在后台发布您的内容:
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
public class SendDataService extends Service {
private final LocalBinder mBinder = new LocalBinder();
protected Handler handler;
protected Toast mToast;
public class LocalBinder extends Binder {
public SendDataService getService() {
return SendDataService .this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
// write your code to post content on server
}
});
return android.app.Service.START_STICKY;
}
}
Run Code Online (Sandbox Code Playgroud)
我的代码的更多解释是:
即使您的应用程序在后台运行,服务也会在后台运行,但请记住它始终在主线程上运行,因为我创建了一个单独的线程来执行后台操作:
服务以粘性方式启动,即使由于任何原因您的服务在后台被销毁,它也会自动重新启动.
有关详细信息,请访问:https: //developer.android.com/guide/components/services.html
并检查您的应用是否在前台/后台代码将有助于:
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
}
// Use like this:
boolean foregroud = new ForegroundCheckTask().execute(context).get();
Run Code Online (Sandbox Code Playgroud)
快乐的编码!!!!
接受的答案不正确。
不幸的是,作者认为将新Runnable任务发布到该Handler()线程会创建一个单独的线程- “我创建了一个单独的线程来执行您的后台操作”:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
// write your code to post content on server
}
});
return android.app.Service.START_STICKY;
}
Run Code Online (Sandbox Code Playgroud)
onStartCommand()回调总是在主线程上调用,新Handler()线程附加到当前线程(即“主”)。所以Runnable任务被发布在主线程队列的末尾。
要解决该问题并Runnable在一个真正独立的线程中执行,您可以将其AsyncTask用作最简单的解决方案:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
// ...
}
});
return android.app.Service.START_STICKY;
}
Run Code Online (Sandbox Code Playgroud)
在复制粘贴任何东西之前先想想自己......
| 归档时间: |
|
| 查看次数: |
19323 次 |
| 最近记录: |