【问题标题】:Are Android.App.Application activity life cycle callbacks invoked on the UI thread?是否在 UI 线程上调用了 Android.App.Application 活动生命周期回调?
【发布时间】:2015-05-22 01:49:01
【问题描述】:

我正在调查我们使用的第三方库 (Xamarin.Insights) 更新后开始出现的性能下降。在我的调查过程中,我在一个大停顿期间停止了应用程序,显示Android.App.Android.OnActivityDestroyed 中隐藏了一个互斥锁。

调用堆栈显示该库利用ActivityLifecycleCallbacks 接口的注册实例来跟踪我们应用程序中的活动生命周期事件。我正在尝试确定是否在 UI 线程上调用了这些回调。

直觉上我认为它们是在 UI 线程上调用的,但我找不到确凿的证据来证实这一点。

  • ActivityLifecycleCallbacks 是否在 UI 线程上调用?
  • 我可以提供一个链接来证明这一点吗?

【问题讨论】:

    标签: java android multithreading android-activity xamarin


    【解决方案1】:

    Android.App.Application.ActivityLifecycleCallbacks 的回调方法确实是在 UI 线程上调用的。

    实现Android.App.Application.ActivityLifecycleCallbacks 接口并记录回调方法的线程ID 表明线程ID 与调用活动的OnCreate 方法的线程相同:

    OnActivityCreated on thread 1
    OnCreate on thread 1
    OnActivityStarted on thread 1
    OnActivityResumed on thread 1
    

    下面的示例可以验证这一点:

    [Activity (Label = "UIThreadsCallbacks", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
    
            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);
    
            Console.WriteLine ("OnCreate on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    }
    
    [Application]
    public class MyApplication : Application
    {
        public MyApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { 
        }
    
        public override void OnCreate ()
        {
            RegisterActivityLifecycleCallbacks(new LifecycleCallbacks());
            base.OnCreate ();
        }
    }
    
    public class LifecycleCallbacks : Java.Lang.Object, Android.App.Application.IActivityLifecycleCallbacks
    {
        public void OnActivityCreated (Activity activity, Bundle savedInstanceState)
        {
            Console.WriteLine ("OnActivityCreated on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivityDestroyed (Activity activity)
        {
            Console.WriteLine ("OnActivityDestroyed on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivityPaused (Activity activity)
        {
            Console.WriteLine ("OnActivityPaused on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivityResumed (Activity activity)
        {
            Console.WriteLine ("OnActivityResumed on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivitySaveInstanceState (Activity activity, Bundle outState)
        {
            Console.WriteLine ("OnActivitySaveInstanceState on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivityStarted (Activity activity)
        {
            Console.WriteLine ("OnActivityStarted on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    
        public void OnActivityStopped (Activity activity)
        {
            Console.WriteLine ("OnActivityStopped on thread " + System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    }
    

    【讨论】:

    • 这应该是公认的答案。另一个答案提供了一个可靠的方法,但实际上并没有直接回答问题。
    【解决方案2】:

    你可以很容易的查看是哪个线程调用了这个方法:

    1. 通过记录Thread.currentThread().getName(),如果是主线程,您会看到类似Main Thread 的内容。
    2. 通过检查当前线程Looper.getMainLooper() == Looper.getMyLooper()的Looper,如果是主线程则为true
    3. 通过在方法中设置断点并在 IDE/调试器的堆栈跟踪中检查线程名称。

    【讨论】:

    • 感谢 Artem,我现在要走这条路了;构建一个示例以在我将使用 Xamarin 填充的错误报告中提交。
    【解决方案3】:

    是的,它确实是在 UI 线程上调用的。 ActivityLifecycleCallbacks 由 Activity.onXXX() 方法调用。例如,下面是 Activity.onCreate() 的源代码。 getApplication().dispatchActivityCreated(this, savedInstanceState); 是调用ActivityLifecycleCallbacks.onActivityCreate()。 所以它在 UI 线程上被调用。

    @MainThread
    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
        if (mLastNonConfigurationInstances != null) {
            mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
        }
        if (mActivityInfo.parentActivityName != null) {
            if (mActionBar == null) {
                mEnableDefaultActionBarUp = true;
            } else {
                mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
            }
        }
        if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                    ? mLastNonConfigurationInstances.fragments : null);
        }
        mFragments.dispatchCreate();
        getApplication().dispatchActivityCreated(this, savedInstanceState);
        if (mVoiceInteractor != null) {
            mVoiceInteractor.attachActivity(this);
        }
        mCalled = true;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多