动态功能活动未加载,在安装时卡住

时间:2018-09-24 13:47:35

标签: android generics app-bundle android-app-bundle

我正在尝试为我的项目实施应用程序捆绑包。在启动动态模块活动时,它正在下载模块并尝试安装该模块,但无法完全安装它。它被卡住,如下图所示。 enter image description here

点击以下链接以供参考。 https://github.com/googlesamples/android-dynamic-features

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.widget.ProgressBar
import android.widget.TextView
import com.google.android.play.core.splitinstall.*
import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus
import com.lenskart.app.R

private const val modulePackageName = "com.test.feature"

private const val htoClassname = "$modulePackageName.hto.HtoActivity"

private const val atHomeClassname = "$modulePackageName.athome.AtHomeActivity"

class BundleActivity : AppCompatActivity() {

    private val listener = SplitInstallStateUpdatedListener { state ->
        val multiInstall = state.moduleNames().size > 1
        state.moduleNames().forEach { name ->
            when (state.status()) {
                SplitInstallSessionStatus.DOWNLOADING -> {
                    displayLoadingState(state, "Downloading $name")
                }
                SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> {
                    startIntentSender(state.resolutionIntent().intentSender, null, 0, 0, 0)
                }
                SplitInstallSessionStatus.INSTALLED -> {
                    displayLoadingState(state, "Installed $name")
                    onSuccessfulLoad(name, launch = !multiInstall)
                }

                SplitInstallSessionStatus.INSTALLING -> displayLoadingState(state, "Installing $name")
                SplitInstallSessionStatus.FAILED -> {
                    Log.e(TAG, "Error: ${state.errorCode()} for module ${state.moduleNames()}")
                }

                SplitInstallSessionStatus.CANCELED -> displayLoadingState(state, "Cancelled $name")
                SplitInstallSessionStatus.UNKNOWN -> displayLoadingState(state, "Unknown thingy $name")
                SplitInstallSessionStatus.PENDING -> displayLoadingState(state, "Pending $name")

            }
        }
    }

    private val moduleHto by lazy { "hto" }
    private val moduleAtHome by lazy { "athome" }

    private lateinit var manager: SplitInstallManager

    private lateinit var progressBar: ProgressBar
    private lateinit var progressText: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_bundle)
        manager = SplitInstallManagerFactory.create(this)
        initializeViews()
        loadAndLaunchModule(moduleAtHome)
    }

    override fun onResume() {
        manager.registerListener(listener)
        super.onResume()
    }

    override fun onPause() {
        manager.unregisterListener(listener)
        super.onPause()
    }

    private fun loadAndLaunchModule(name: String) {
        updateProgressMessage("Loading module $name")
        if (manager.installedModules.contains(name)) {
            updateProgressMessage("Already installed")
            onSuccessfulLoad(name, launch = true)
            return
        }
        val request = SplitInstallRequest.newBuilder()
                .addModule(name)
                .build()

        manager.startInstall(request)

        updateProgressMessage("Starting install for $name")
    }

    private fun onSuccessfulLoad(moduleName: String, launch: Boolean) {
        if (true) {
            when (moduleName) {
                moduleHto -> launchActivity(htoClassname)
                moduleAtHome -> launchActivity(atHomeClassname)
            }
        }

        displayButtons()
    }

    private fun launchActivity(className: String) {
        Intent().setClassName(packageName, className)
                .also {
                    startActivity(it)
                }
    }

    private fun displayLoadingState(state: SplitInstallSessionState, message: String) {
        displayProgress()

        progressBar.max = state.totalBytesToDownload().toInt()
        progressBar.progress = state.bytesDownloaded().toInt()

        updateProgressMessage(message)
    }

    private fun initializeViews() {
        progressBar = findViewById(R.id.progress_bar)
        progressText = findViewById(R.id.progress_text)
    }

    private fun updateProgressMessage(message: String) {
        if (progressText.visibility != View.VISIBLE &&
                progressBar.visibility != View.VISIBLE) displayProgress()
        progressText.text = message
    }

    private fun displayProgress() {
        progressText.visibility = View.VISIBLE
        progressBar.visibility = View.VISIBLE
    }

    private fun displayButtons() {
        progressText.visibility = View.GONE
        progressBar.visibility = View.GONE
    }

}

private const val TAG = "DynamicFeatures"

3 个答案:

答案 0 :(得分:2)

根据文档,还需要启用SplitCompat。您有3种选择:

  • 选项1:通过在AndroidManifest.xml中定义SplitCompatApplication作为默认应用程序

    <application
        ...
        android:name="com.google.android.play.core.splitcompat.SplitCompatApplication" >
    </application>
    
  • 选项2:让您当前的应用程序类扩展SplitCompatApplication。

    public class MyApplication extends SplitCompatApplication {
        ...
    }
    
  • 选项3:从您的应用程序覆盖attachBaseContext方法。

    @Override
    protected void attachBaseContext(Context context) {
        super.attachBaseContext(context);
        // Emulates installation of future on demand modules using SplitCompat.
        SplitCompat.install(this);
    }
    

Source

答案 1 :(得分:0)

@Override protected void attachBaseContext(Context context) { super.attachBaseContext(context); }

扩展SplitCompatApplication

答案 2 :(得分:-2)

Уменябылатакаяпроблема,виз-заинициализациилиснеравполе

private val listener = SplitInstallStateUpdatedListener{}

Какпофиксить,переместитьвфункциюloadAndLaunchModule! Пример:

override suspend fun processInstallDynamicFeature(idDynamicFeature: String) {
    val request = createRequestOnInstallModules(idDynamicFeature)

    @SuppressLint("SwitchIntDef")
    val listener = SplitInstallStateUpdatedListener { state ->
        if (state.sessionId() == sessionId) {
            with(splitInstallSessionStateChannel) {
                when (state.status()) {
                    SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> offer(InstallStateForFeature(idDynamicFeature, state))
                    SplitInstallSessionStatus.DOWNLOADING -> offer(InstallStateForFeature(idDynamicFeature, state))
                    SplitInstallSessionStatus.INSTALLING -> offer(InstallStateForFeature(idDynamicFeature, state))
                    SplitInstallSessionStatus.INSTALLED -> offer(InstallStateForFeature(idDynamicFeature, state))
                    SplitInstallSessionStatus.FAILED -> offer(InstallStateForFeature(idDynamicFeature, state))
                    else -> Log.crashlyticsProductionLog(UnhandledStateException("Unhandled state: ${state.status()}, feature $idDynamicFeature"))
                }
            }
        }
    }
    splitInstallManager.registerListener(listener)

    splitInstallManager.startInstall(request)
            .addOnSuccessListener { sessionId = it }
            .addOnFailureListener { Log.crashlyticsProductionLog(InstallAppletException("Failed install: ${it.message}")) }
}