1

我刚刚开始学习 Android 应用程序开发,并且正在为嵌入式设备开发应用程序。我的应用程序需要长时间运行,但它没有这样做。我清理了可能存在内存泄漏的代码,但问题仍然存在。

因此,我尝试在一夜之间运行一个什么都不做的应用程序,这是我的发现。

首先,源代码片段:

@RequiresApi(api = Build.VERSION_CODES.N)
public MainActivity()
{
    super();
    Log.d("TEST","NEW INSTANCE CREATED " + Calendar.getInstance().getTime()+"=================================================");
}

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    ((TextView)findViewById(R.id.textHere)).setText(Calendar.getInstance().getTime()+"");
}

然后是隔夜日志:

    $ adb shell am start -n "domain.removed.myapplication/domain.removed.myapplication.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
    Client not ready yet..Waiting for process to come online
    Connected to process 1324 on device freescale-ivg_mx6dq-1126a9d4e315e294
    I/art: Late-enabling -Xcheck:jni
    I/art: Debugger is no longer active
    W/System: ClassLoader referenced unknown path: /data/app/domain.removed.myapplication-2/lib/arm
    I/InstantRun: Instant Run Runtime started. Android package is domain.removed.myapplication, real application class is null.
    W/System: ClassLoader referenced unknown path: /data/app/domain.removed.myapplication-2/lib/arm
    D/TEST: NEW INSTANCE CREATED Tue Jan 25 19:00:45 GMT+08:00 2011=================================================
    W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
    D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
    I/imx6.gralloc: open gpu gralloc module!
    I/OpenGLRenderer: Initialized EGL, version 1.4
    D/TEST: NEW INSTANCE CREATED Wed Jan 26 04:08:19 GMT+08:00 2011=================================================
    D/TEST: NEW INSTANCE CREATED Wed Jan 26 05:10:15 GMT+08:00 2011=================================================
    D/TEST: NEW INSTANCE CREATED Wed Jan 26 06:13:26 GMT+08:00 2011=================================================
    D/TEST: NEW INSTANCE CREATED Wed Jan 26 07:15:13 GMT+08:00 2011=================================================
    W/art: Suspending all threads took: 32.077ms
    W/art: Suspending all threads took: 28.910ms
    W/art: Suspending all threads took: 29.957ms
    W/PathParser: Points are too far apart 4.000000596046461

根据日志,应用程序重新实例化了五次。

我的问题:

  1. 为什么Android会这样?
  2. 处理这个问题并实现我想要的行为的最佳实践是什么?(无需重新实例化即可长时间运行的应用程序)
  3. 如果这也是 Android 开发人员的常识,您能否建议/推荐关键词或搜索词以查找与此相关的问题?

提前谢谢大家!:)

乔伊

4

4 回答 4

0

Joey,首先,这并不是一个真正的“问题”,因为您知道几乎所有的 android 设备都是电池供电的,而省电是 android 运行时(ART 或 Delvik)的主要目标之一。为了回答您的问题,

  1. 为什么Android会这样?

如果您的活动没有做任何有效的“工作”,那么 android 系统将暂停您的应用程序/应用程序和休眠/睡眠/进入省电模式等。

W/art: Suspending all threads took: 32.077ms
W/art: Suspending all threads took: 28.910ms
W/art: Suspending all threads took: 29.957ms

这些行表明了我刚才所说的。它是 android 的工作原理,不要惊慌。

  1. 处理这个问题并实现我想要的行为的最佳实践是什么?(无需重新实例化即可长时间运行的应用程序

好吧,如果您的应用程序实际上正在做某事,那么该应用程序将不会进入休眠状态,从我在您的MainActivity中看到的内容来看,您的活动什么都不做。它是一个简单的 UI,就在那里。所以 android 运行时认为这个应用程序没有做任何事情 => 暂停/终止应用程序。

  1. 如果这也是 Android 开发人员的常识,您能否建议/推荐关键词或搜索词以查找与此相关的问题?

检查 thealeksandr 的答案,将长进程作为后台服务运行。希望这会有所帮助..干杯..!!

于 2017-02-10T04:51:18.313 回答
0

抱歉,我花了一段时间才更新此内容,您对我的问题 1 的回答使我找到了满足我的应用要求的完美解决方案。

我将我的应用添加到电池优化白名单中,查看以下链接了解更多信息。 电池优化

于 2017-02-15T01:51:09.313 回答
0

你不能让你的应用程序一直运行。对电池不好。如果您在后台的应用程序可以杀死它以释放另一个应用程序的资源。或出于任何其他原因,例如节能或其他原因。

如果您需要在后台执行某些操作。您需要使用服务

使用AlarmManager,您可以安排服务何时启动并完成一些工作。

但在 Android 6 中,谷歌添加了打盹模式。当设备在一段时间后进入深度睡眠并且只有针对打盹模式进行了优化的应用程序才能唤醒。

于 2017-02-10T03:41:29.060 回答
0

当您的代码覆盖 Application 对象时,可能会发生繁重的应用程序初始化。应用程序初始化经常发生,因为垃圾收集的数量很多,但是由于您已经告诉您已经检查过内存泄漏,这可能/可能不是主要问题。您可以使用此处提到的方法跟踪或内联跟踪。

您可以通过简化 UI 来避免重复的应用程序初始化,避免活动中子系统的复杂初始化。

按照链接上的内容进行操作 - 如果您学到了除我所说的内容之外的新内容,请回复此评论。这对我来说也是一个很好的学习:)

干杯!

于 2017-02-10T04:46:59.473 回答