标签: android-lifecycle

使用多个Activity时,Activity进入前台后如何处理保留数据?

目前我对 Android 中的生命周期管理有点困惑。Activity 回到前台后,至少有 4 种可能来恢复保留的数据:

  • Android处理:如果有足够的内存,Android在Activity重启后存储和恢复重要数据(选中的单选按钮,EditText的文本,-...等),用户与Activity进入之前的状态相同背景。

  • onPause、onResume:覆盖onPause,将重要数据保存到数据库或文本文件中,下次执行onResume时恢复。

  • onSavedInstance(Bundle), onRestoreInstance(Bundle):我可以将数据作为键值对保存到包中,并在执行 onRestoreInstance 后恢复它们。

  • onRetainNonConfigurationInstance()、getLastNonConfigurationInstance():我在一个大对象中处理所有存储问题,并在执行 onCreate 时读取 getLastNonConfigurationInstance()。

尽管哪种方法最好令人困惑,但我想它依赖于开发经验来知道何时使用哪种可能性。如果你有一些很好的例子,我会很高兴,但这不是我的问题。我想知道当我有不同的 Activity 并且一个 Activity 在后台暂停时会被 Android 杀死时如何处理所有这些:

就我而言,我有一个 MainActivity 和一个 MessageActivity。MessageActivity 由一个 ViewSwitcher 组成,该 ViewSwitcher 由两个状态组成。状态一是单选按钮选择列表。状态二是一个带有两个按钮(发送和中止)的 EditText。当我对每个状态进行猴子测试,点击 Android 主页按钮并重新启动应用程序时,当我将处理留给 Android 时,具有正确状态和旧数据的正确 Activity 进入前台。所以这有效。
但是当Android在后台销毁MessageActivity时会发生什么:如果我使用Android方式,数据会丢失,我猜MainActivity(而不是MessageActivity->state(1或2))将在我重新启动应用程序(是对吗?)。所以当我想保留 MessageActivity 的数据时,我必须使用其他三种可能性之一。
当应用程序入口点(即 MainActivity)与上一个活动 Activity 不同时,如何巧妙地做到这一点。问题是我必须恢复具有特殊状态的 ViewSwitcher 的特殊活动。我可以使用 onStart() 或 onResume() 方法中的 startActivity(Intent) 从 MainActivity 启动 MessageActivity(因为 MainActivity 可能是入口点),但随后我在生命周期管理中遇到了很多逻辑问题。由于这个事实,我不认为这是做到这一点的正确方法。

但是,这样做的正确和最佳方法是什么?

android activity-lifecycle android-lifecycle

5
推荐指数
1
解决办法
4773
查看次数

如何检查活动是否可见?onResume是不够的

我的一项活动是嵌入VideoView一些内容.我实现暂停/恢复视频onPause()onResume()分别,但让我吃惊- onResume被称为前的活动是用户真正可见.

确切地说,情况如下:

  • 活动在屏幕上,视频正在播放
  • 用户使用电源按钮锁定手机
  • 活动被onPause()调用,视频停止
  • 用户按下电源按钮
  • 在用户解锁屏幕之前,活动被 onResume()调用(从而恢复视频)

我用Android 2.2,2.3和4.0确认了这个行为.我想它是故意这样做的,让活动准备在锁定屏幕消失后立即重绘.

如何检测活动实际出现在用户身上的时刻?我试图等待onWindowFocusChanged(true)被叫,它似乎有效,但它并没有让我觉得非常安全.

android android-lifecycle android-activity

5
推荐指数
1
解决办法
9236
查看次数

后退和向上导航有不同的结果

我遇到了活动导航的问题,我无法弄清楚我做错了什么.

我有一个MainActivity和一个SettingsActivity但是使用BackUp(在操作栏上)有两个不同的设置活动结果.

例如,如果我按下后退按钮,我会在以下内容中获得以下生命周期回调MainActivity:

V/lifeCycle: onOptionsItemSelected
V/lifeCycle: onPause
V/lifeCycle: onSaveInstanceState-Bundle[..]
V/lifeCycle: onStop
<< PRESS BACK BUTTON >>
V/lifeCycle: onRestart
V/lifeCycle: onStart
V/lifeCycle: onResume
V/lifeCycle: onPostResume
Run Code Online (Sandbox Code Playgroud)

如果我按下导航向上按钮,我会得到以下结果:

V/lifeCycle: onOptionsItemSelected
V/lifeCycle: onPause
V/lifeCycle: onSaveInstanceState-Bundle[..]
V/lifeCycle: onStop
<< PRESS NAV UP >>
V/lifeCycle: onDestroy // Problem
V/lifeCycle: onCreate  // Seems
V/lifeCycle: onStart   // Here
V/lifeCycle: onResume
V/lifeCycle: onPostResume
Run Code Online (Sandbox Code Playgroud)

问题是,当我按下Nav UP我的主要活动被销毁并重新创建意味着我放松了所有视图状态,但按下后退按钮不会这样做.

我不确定这是不是我的开始PreferenceActivity:

Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            return true; …
Run Code Online (Sandbox Code Playgroud)

android android-manifest android-lifecycle android-activity android-actionbar

5
推荐指数
1
解决办法
1412
查看次数

Android:当服务被杀死时,我们如何能够保留服务状态以便以后恢复?

我们创建了一个应用程序,它本质上是一个带有一些装饰功能的计时器/秒表.我们定义了一个服务,该服务勾选时钟并警告订阅某些计时器事件的听众(活动等).

我们希望能够保存计时器/秒表的状态(经过的秒数,直到下一个事件的时间,用户提供的配置等)每当android杀死我们的服务(用于记忆回忆),然后恢复服务的状态当用户恢复应用程序时. 对我们来说,这意味着可能保留和恢复对象及其状态. 我们的服务有很多组成.基本上,我们的服务由我们所有的计时器模型组成,其中服务死亡时死亡.

有什么策略可以坚持服务的状态?对于我们的目的,PreferencesManager可能不够强大,尽管它可能是.我们可以依靠Service onDestroy()方法来保存状态(例如在SQLite中)吗?如果android决定杀死我们的进程,它是否甚至保证将调用onDestroy()服务?

谢谢!

android android-service android-lifecycle

5
推荐指数
1
解决办法
3662
查看次数

如何在onAttach(活动活动)被解除后检查活动是否实现了接口

由于onTttach(Activity)已在SDK 23上弃用,这是Fragment生命周期中用于检查Activity是否正在实现接口的最佳方法?

此代码不再正确,将来甚至可以删除此方法.

 @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (activity instanceof OnInterfaceOfFragmentListener)
            mCallback = (OnInterfaceOfFragmentListener) activity;
        else
            throw new RuntimeException("OnInterfaceOfFragmentListener not implemented in activity");

    }
Run Code Online (Sandbox Code Playgroud)

android android-lifecycle android-fragments android-fragmentactivity

5
推荐指数
1
解决办法
2356
查看次数

AsyncTask和运行时配置更改:Android团队认可哪些方法,简洁的代码示例?

自从2009 AsyncTask年在Cupcake(API 3,Android 1.5)中推出以来,它一直被Android团队一直推广为:

他们提供的代码示例强化了这种简单的信息,特别是对于那些不得不以更痛苦的方式使用线程的人.AsyncTask非常有吸引力.

然而,在此后的许多年里,崩溃,内存泄漏和其他问题困扰了大多数选择AsyncTask在其生产应用程序中使用的开发人员.这通常是由于Activity 破坏和娱乐上运行时配置的变化(特别是取向/旋转),而AsyncTask运行doInBackground(Params...); 当onPostExecute(Result)被调用时,Activity已经被破坏,使UI引用处于不可用状态(或甚至null).

Android团队在这个问题上缺乏明显,清晰,简洁的指导和代码样本只会让事情变得更糟,导致混乱以及各种变通方法和黑客攻击,有些体面,有些可怕:

显然,既然AsyncTask可以在很多情况下使用,那么就没有一种方法可以解决这个问题.然而,我的问题是关于选择.

什么是规范(由Android团队认可)最佳实践,使用简洁的代码示例,AsyncTaskActivity/ Fragmentlifecycle 集成并在运行时配置更改时自动重启?

android android-lifecycle android-configchanges android-asynctask android-memory

5
推荐指数
1
解决办法
833
查看次数

如何检测方向变化但让android处理它们?

我有一个非常类似的问题:Android - ActionBar没有使用onConfigurationChanged(AppCompat)调整大小

我需要让android处理方向更改,因为我想重新创建活动.

但是,我还需要检测何时产生了方向变化.

这两项综合需求是否能够立即实现?

android screen-orientation oncreate android-lifecycle android-orientation

5
推荐指数
0
解决办法
2091
查看次数

LifecycleObserver无法正常工作

没有调用Observer方法.我ViewPagerCycler按照旧学校的方式测试并且工作完美.感谢帮助.

public final class ViewPagerCycler implements LifecycleObserver {

    private static final int PERIOD = 3000;

    private Timer mTimer;
    private TimerTask mTask;
    private Activity mActivity;
    private ViewPager mPager;

    public ViewPagerCycler(Activity activity, ViewPager pager) {
        mActivity = activity;
        mPager = pager;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void start() {
        int count = mPager
            .getAdapter()
            .getCount();

        mTimer = new Timer();
        mTask = new TimerTask() {
            @Override public void run() {
                mActivity.runOnUiThread(new TimerTask() {
                    @Override public void run() {
                        mPager.setCurrentItem((mPager.getCurrentItem() + 1) % count, …
Run Code Online (Sandbox Code Playgroud)

android android-lifecycle android-architecture-components

5
推荐指数
2
解决办法
7568
查看次数

来电期间活动生命周期的怪异行为:延迟onStop()

我有一个没有UI的简单活动。我想在通话期间检查活动的生命周期方法。

呼叫通知到达时,没有发生任何预期的情况。当我接受呼叫时,呼叫活动掩盖了我的活动。因此,理想情况下onStop()应立即调用。我已经检查了日志,仅onPause()在接受呼叫时才被呼叫。但是2-3秒后onStop()也被调用。

活动

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

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

    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "onStart: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "onStop: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "onResume: ");
    }
}
Run Code Online (Sandbox Code Playgroud)

表现

   <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category …
Run Code Online (Sandbox Code Playgroud)

java android android-lifecycle android-activity

5
推荐指数
1
解决办法
755
查看次数

在启动对话活动并重新创建活动时未调用OnActivityResult

我有两个活动,A和B. A调用了B startActivityForResult().B有主题@android:style/Theme.Dialog.

因此,B显示在"A"之上,但A仍然可见(因为B是对话框).

当两个活动都启动时,我通过切换到另一个任务并返回来强制重新创建(我在android开发人员设置中启用了"不要保持活动"选项.当我返回到我的任务时,我看到在A和B上调用OnCreate .)

当我点击活动B按钮,它调用setResult()finish(),但onActivityResult() 不叫上.

问题没有出现

  • 如果我不强制重新开展活动

要么

  • 如果我从活动B中删除对话框主题.

我在使用Android 9的Google Pixel上测试了这个.

这是预期的行为还是Android中的错误?


这是我用来测试它的代码(Xamarin Android):

[Activity(Label = "@string/app_name")]
public class ActivityA : Activity
{

    protected override void OnCreate(Bundle savedInstanceState)
    {
        Kp2aLog.Log("OnCreate A");
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.yubichall_test);

        {
            FindViewById<Button>(Resource.Id.btn_yubichall).Text = "Start B";
            FindViewById<Button>(Resource.Id.btn_yubichall).Click += (sender, args) =>
            {

                var chalIntent = new Intent(this, typeof(ActivityB));

                StartActivityForResult(chalIntent, 123);

            };
        }


    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, …
Run Code Online (Sandbox Code Playgroud)

android dialog xamarin.android android-lifecycle

5
推荐指数
0
解决办法
270
查看次数