安卓数据存储性能

4
我正在开发一款具有数据存储功能的Android应用程序,并按照以下方式进行操作:
Activity -> 业务服务 -> 存储库(使用Spring REST框架)。使用这种方法,我被迫在关闭它之前让活动完成它的存储工作(线程处理、进度对话框等)。
使用Android服务来存储数据是一种不好的编码方式吗?
通过这种方式,用户可以继续浏览,并且有一种非常流畅的应用程序使用体验。这是一个好的解决方案吗?
谢谢
1个回答

26

没有必要将您的活动保持在前台,等待后台逻辑完成。

相反,您应该以一种与您的活动“分离”的方式执行此后台逻辑。

解决此问题有两种方法:风险和安全。


风险方法

class MyActivity extends Activity {

     void calledWhenActivityNeedsToBeClosed() {

          // start a thread to do background work
          new Thread() {
                public void run() {
                     perform long running logic here
                }
          }.start();

          // and clos the activity without waiting for the thread to complete
          this.finish();
     }
}

你可以使用AsyncTask或任何java.concurrent构造来代替线程,它们都能完成工作。

我多年来一直使用这种方式。它大部分情况下都可以正常工作。但是...它本质上是有缺陷的。
为什么?因为一旦活动被finish()了,Android随时可以收回它以及它所有的资源,包括暂停所有工作线程。
如果您的长时间运行的工作不超过几秒钟,并且我假设您的存储库更新也是如此,那么这里的风险是很小的。但是,为什么要冒这个险呢?


安全的方法

声明一个Service,在活动关闭之前激活它来执行长时间运行的操作:

class MyActivity extends Activity {

     void calledWhenActivityNeedsToBeClosed() {

          // delegate long running work to service
          startService(this, new Intent(this, MyWorkerService.class));

          // and close the activity without waiting for the thread to complete
          this.finish();
     }

}


这样会安全得多。Android 也可以杀死正在运行的服务,但是相比杀死后台活动,它会更加不情愿地这样做。


请注意,如果您可以想象出一种情况,在这种情况下,当工作服务仍在运行时,您的 UI 是可见的,那么您可能希望改用IntentService


最后 - 如果您想绝对确保后台逻辑不被 Android 清除,您应该使用前台服务。下面是如何实现的,但请注意 - 在像您描述的情况下,前台服务可能是过度设计:

static final int NOTIF_ID = 100;

// Create the FG service intent 
Intent intent = new Intent(getApplicationContext(), MyActivity.class); // set notification activity
showTaskIntent.setAction(Intent.ACTION_MAIN);
showTaskIntent.addCategory(Intent.CATEGORY_LAUNCHER);
showTaskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent pIntent = PendingIntent.getActivity(
                getApplicationContext(),
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

Notification notif = new Notification.Builder(getApplicationContext())
                .setContentTitle(getString(R.string.app_name))
                .setContentText(contentText)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(pIntent)
                .build();

startForeground(NOTIF_ID, notif);

谢谢你的回答。那么,如果有一个服务在后台运行,每次都旨在存储尚未保存的数据,当我们获得网络连接时,这样做是否是一种不好的方式来存储数据?需要时将服务绑定到活动上吗? - mfrachet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接