我的 Android 4+ 应用程序连接到自定义 Web 服务,用于每隔几分钟同步一次数据。为了确保在线数据始终是最新的,我想在应用程序关闭/发送到后台时触发同步。
在 iOS 下这很简单:
- 听
applicationDidEnterBackground:
在应用程序委托中
- Use
beginBackgroundTaskWithName:
启动长时间运行的后台任务并避免在任务仍在运行时被挂起
如何在 Android 上执行此操作?
第一个问题是,没有什么相当于applicationDidEnterBackground:
。到目前为止我发现的所有解决方案都建议使用主要活动onPause()
方法。然而,这在任何时候都被称为主要Activity
已暂停,当另一个Activity
在应用程序内启动。对于onActivityPaused()
方法来自ActivityLifecycleCallbacks
界面。
那么,如何检测app(不仅仅是一个Activity
)是关闭还是发送到后台?
第二个问题是,我没有找到任何有关如何运行后台任务的信息。所有解决方案都指向简单地启动一个AsyncTask
,但这真的是正确的解决方案吗?
AsyncTask
将启动一个新任务,但是当应用程序关闭/不活动时,该任务也会运行吗?我必须做什么才能防止应用程序和任务在几秒钟后挂起?在应用程序完全挂起之前,我如何确保任务可以完成?
以下代码将帮助您在应用程序关闭或在后台时发布内容:
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;
}
}
我的代码的更多解释是:
即使您的应用程序位于后台,服务也会在后台运行,但请记住,它始终在主线程上运行,因此我创建了一个单独的线程来执行后台操作。
服务作为粘性服务启动,即使由于任何原因您的服务在后台被破坏,它也会自动重新启动。
更多详情可在这找到:https://developer.android.com/guide/components/services.html 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();
快乐编码!!!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)