在后台检查新数据

时间:2015-09-25 21:03:40

标签: android xamarin

无论应用程序位于前台还是后台,检查新数据的建议方法是什么?我想知道哪些Android API用户通常会这样做。似乎有几种方法可以实现我的目标,我想确保我走在正确的道路上。

我有一些东西放在一起,使用<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" /> <script src="https://code.jquery.com/jquery-1.9.1.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.full.min.js"></script> <select name="" id="akshay"> <option value="item-1">Value</option> <option value="item-2">Item 2</option> <option value="item-3">Item 3</option> <option value="item-4">Item 4</option> <option value="item-5">Item 5</option> <option value="item-6">Item 6</option> <option value="item-7">Item 7</option> <option value="item-8">Item 8</option> <option value="item-9">Item 9</option> <option value="item-10">Item 10</option> <option value="item-11">Item 11</option> <option value="item-12">Item 12</option> <option value="item-13">Item 13</option> <option value="item-14">Item 14</option> <option value="item-15">Item 15</option> </select>来调用AlarmManager.SetInexactRepeating()来执行同步并在数据库中插入/更新数据。这可以在应用程序处于前台和后台时工作,但如果我强制停止应用程序,那么当AlarmManager警报被触发时,我会一直看到“不幸的是,已停止工作”消息。在这种情况下,我只关心在应用程序在前台或后台运行时检查新数据。

我的第一个想法是检测应用程序何时强制关闭,并停止警报,但这似乎不可能。所以我在这里问,我的方法是错的吗?如果是这样,无论手机是在前台还是在后台,都使用哪种方法执行某些周期性任务?我正在使用的AlarmManager解决方案的问题是即使关闭应用程序也会继续触发警报。

3 个答案:

答案 0 :(得分:2)

对于Android上的后台处理,通常你甚至可以使用一个可以独立运行的服务,也可以独立于App或从应用程序获取和返回数据的Bounded服务。可以找到关于背景的完整参考here

答案 1 :(得分:2)

如果您的想法是检查您的API是否有新数据并执行后台同步到本地数据库或其他数据存储,我想您想看一下:

Creating a Sync Adapter

Running a Sync Adapter

同步适配器是在Android中实现此目的的推荐方式。使用它的优点是多方面的:

  • 开箱即用的优化 - 操作系统捆绑调用,使用最合适的窗口以最小的带宽和电池成本运行同步适配器
  • 后台同步组件的生命周期由操作系统内部管理
  • 当数据发生变化时,可以通知观察者,以便轻松更新用户界面
  • 多种运行同步的方式 - 每隔一段时间,自动与OS消息一起打开或按需打开TCP / IP连接

然而,实现这一点需要一些事情,这可能会引起一些痛苦:

  • 适配器必须使用ContentProvider
  • 同步适配器使用帐户进行身份验证。如果不需要,则必须提供存根

答案 2 :(得分:1)

使用服务是正确的方法。让您的应用启动服务,它将在应用处于前台或后台时继续运行。然后,如果您想在应用关闭时终止该服务,则只需在应用活动的stopService(yourServiceIntent);覆盖中拨打onDestroy()即可。这应该会在应用关闭时有效地关闭服务。

所以一些示例代码如何工作(取自Services文档)......

服务(仅每1秒记录一次消息60秒):

public class MyService extends Service {
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    // Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {

            long endTime = System.currentTimeMillis() + 60*1000;
            while (System.currentTimeMillis() < endTime) {
                synchronized (this) {
                    try {
                        wait(1000);
                        Log.d("SERVICE", "The service is still running.");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            stopSelf(msg.arg1);
        }
    }

    @Override
    public void onCreate() {

        HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        mServiceHandler.sendMessage(msg);

        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {

    }
}

在你的活动中,你会做类似的事情:

public class MainActivity extends AppCompatActivity {

    Intent serviceIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        serviceIntent = new Intent(this, MyService.class);
        startService(serviceIntent);
    }

    @Override
    protected void onDestroy() {
        stopService(serviceIntent);
        super.onDestroy();
    }