从另一个 activity 启动一个 activity 会跳过很多 (96) 帧

Launching an activity from another activity skips a lot (96) frames

我有一个应用程序有两个活动 - LoginActivity (LA) 和 AppActivity (AA)。正如你所猜到的,LA 在登录成功后启动 AA。出于调试目的,我删除了所有登录逻辑,并用启动 AA 的简单按钮替换它。

AA 包含在 Fragment 上,它包含一个具有三个视图的 viewpager,其中一个视图使用 Kotlin 协程读取音乐文件并填充到 Recyclerview 中。其他两个视图做一些不同的事情,不涉及任何类型的文件 I/O 或 api 请求,简单静态 UI.

每当我启动该应用程序时,我都会看到三次跳帧警告

  1. 在洛杉矶点击按钮启动 AA(跳过 40 帧)
  2. AA 开始时(跳过 74 帧)
  3. 在 AA 完整加载包括子片段(跳过 38 帧)

我已经尝试 android studio profiler 来找出导致此问题的原因,但我没有这样做。

 

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_login)
    
            /*Permissions*/
            val permissions = listOf(
                    Manifest.permission.INTERNET,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.CAMERA,
                    Manifest.permission.RECORD_AUDIO
            )
            validatePermission(permissions)
        }
    
        fun startActivity(view: View) {
            val intent = Intent(this, AppActivity::class.java)
            startActivity(intent)
            finish()
        }
    
        private fun validatePermission(permissions: List<String>) {
            Dexter.withContext(this)
                    .withPermissions(permissions)
                    .withListener(
                            object : MultiplePermissionsListener {
                                override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
    
                                }
    
                                override fun onPermissionRationaleShouldBeShown(
                                        p0: MutableList<PermissionRequest>?,
                                        p1: PermissionToken?
                                ) {
                                    AlertDialog.Builder(this@LoginActivity)
                                            .setTitle(R.string.storage_permission_rationale_title)
                                            .setMessage(R.string.storage_permission_rationale_message)
                                            .setNegativeButton(
                                                    android.R.string.cancel,
                                                    DialogInterface.OnClickListener { dialogInterface, i ->
                                                        dialogInterface.dismiss()
                                                        p1?.cancelPermissionRequest()
                                                    })
                                            .setPositiveButton(
                                                    android.R.string.ok,
                                                    DialogInterface.OnClickListener { dialogInterface, _ ->
                                                        dialogInterface.dismiss()
                                                        p1?.continuePermissionRequest()
                                                    })
                                            .show()
                                }
                            }
                    ).check()
        }   


编辑:我发现了跳帧的问题之一。语音合成 onCreate 中的引擎初始化导致问题。所以我把它 在一个线程中,但我仍然有跳帧问题 现在它不像以前那么高,但仍然很重要。还是三个跳帧的警告。


    class AppActivity : AppCompatActivity(),  TextToSpeech.OnInitListener{
    
        private lateinit var appBarConfiguration: AppBarConfiguration
    
     
    
    
        private var engine: TextToSpeech? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_app)
            val toolbar: Toolbar = findViewById(R.id.toolbar)
            setSupportActionBar(toolbar)
    
            val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
            val navView: NavigationView = findViewById(R.id.nav_view)
            val navController = findNavController(R.id.nav_host_fragment)
            // Passing each menu ID as a set of Ids because each
            // menu should be considered as top level destinations.
            appBarConfiguration = AppBarConfiguration(setOf(
                    R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow), drawerLayout)
            setupActionBarWithNavController(navController, appBarConfiguration)
            navView.setupWithNavController(navController)
    
            /*---Text to speech------*/
           
        }
    
        override fun onStart() {
            super.onStart()
             Thread(Runnable {
                     engine = TextToSpeech(this, this) 
             }).start()
        }
    
        override fun onCreateOptionsMenu(menu: Menu): Boolean {
            // Inflate the menu; this adds items to the action bar if it is present.
            menuInflater.inflate(R.menu.main, menu)
            return true
        }
    
        override fun onSupportNavigateUp(): Boolean {
            val navController = findNavController(R.id.nav_host_fragment)
            return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
        }
    
        override fun onResume() {
            super.onResume()
            realTimeData()
        }
     
    
        /*---Test Code-----------*/
        private var mHandler: Handler = Handler(Looper.myLooper()!!)
        private lateinit var mTimer2:Runnable
        private fun realTimeData(){
            mTimer2 = object : Runnable {
                override fun run() { 
                    mHandler.postDelayed(this, 200)
                }
            }
            mHandler.postDelayed(mTimer2, 200)
        }
    
        var mRand: Random = Random()
        private fun getRandom(): Double {
            return mRand.nextDouble() * 100
        }
    
        private fun playMessage(msg: String) {
            engine!!.speak(msg, TextToSpeech.QUEUE_FLUSH, null, null)
        }
    
        override fun onDestroy() {
            super.onDestroy()
            if (engine != null) {
                engine!!.stop()
                engine!!.shutdown()
                Log.d("TTS", "TTS Destroyed")
            }
        }
    
        override fun onInit(status: Int) {
            if (status == TextToSpeech.SUCCESS) {
                val results = engine!!.setLanguage(Locale.US)
                if (results == TextToSpeech.LANG_MISSING_DATA
                        || results == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Toast.makeText(this, "Not supported", Toast.LENGTH_LONG).show()
                }
            }
        }
    }


我还注释掉了 viewPager,其他两个跳帧警告都消失了。现在,我不想删除viewpager,所以我还在调试,很快就会在这里更新。

我在几个应用程序中遇到了同样的问题,

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_app)
    val toolbar: Toolbar = findViewById(R.id.toolbar)
    setSupportActionBar(toolbar)
    
    val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
    val navView: NavigationView = findViewById(R.id.nav_view)
    val navController = findNavController(R.id.nav_host_fragment)
    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    appBarConfiguration = AppBarConfiguration(setOf(
    R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow), drawerLayout)
    setupActionBarWithNavController(navController, appBarConfiguration)
    navView.setupWithNavController(navController)

   // Oncreate is the place for the initialization of things but if their initialization is CPU intensive then delaying them a bit will make things hassle-free.

   Handler(Looper.getMainLooper()).postDelayed({
          engine = TextToSpeech(this, this)
          observers()//perform other intensive task after a delay,e.g. loading a url on webview.
  },200)//delayed by 200ms, 
 }

当我们启动一个activity时,activity将在oncreate完成并调用onstart后立即启动,所以我们必须让onCreate顺利完成,这将使activity立即启动。