【问题标题】:Using Dynamic App feature in Base application在基本应用程序中使用动态应用程序功能
【发布时间】:2019-06-16 18:13:46
【问题描述】:

假设我的基础应用程序 A 带有 com.package.a 包名称,B 带有 com.package.b 是我的动态应用程序功能,将在安装基本 apk 后我的基本应用程序。 了解更多dynamic Feature 现在我的 B(动态功能项目)中有一个布局,我想在我的基本应用程序 A 中访问它。我尝试了 this,但它不适合我。

这是我想从动态功能应用程序 B 访问的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/lottie_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".LottieAnimationActivity">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/lottie_animation_view"
        android:layout_width="match_parent"
        android:background="@color/white"
        app:lottie_fileName="animation.json"
        android:layout_height="wrap_content" />

</RelativeLayout>

这就是我在我的活动中这样做的方式

public class SplashActivity extends Activity {
@BindView(R.id.splash_logo)
ImageView splash_logo;

private int sessionID;
private boolean dynamicModule = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(this);
        SplitInstallRequest request = SplitInstallRequest
                .newBuilder()
                .addModule("lottie")
                .build();
        SplitInstallStateUpdatedListener listener = new SplitInstallStateUpdatedListener() {
            @Override
            public void onStateUpdate(SplitInstallSessionState splitInstallSessionState) {
                if(splitInstallSessionState.sessionId() == sessionID) {
                    switch (splitInstallSessionState.status()) {
                        case SplitInstallSessionStatus.INSTALLED:
                            Log.v("lottie", "lottie Module installed");
                          
                            try
                            {
                                PackageManager manager = getPackageManager();
                                Resources resources = manager.getResourcesForApplication("com.package.b");
                                int resId = resources.getIdentifier("lottie_animation_view", "layout", "com.package.b");
                                RelativeLayout alayout = (RelativeLayout) resources.getLayout(resId);
                                setContentView(resId);

                                }
                            catch (Exception e)
                            {
                                e.printStackTrace();
                                setContentView(R.layout.activity_splash);
                                Toast.makeText(SplashActivity.this, "error", Toast.LENGTH_LONG).show();

                            }
                            break;
                        case SplitInstallSessionStatus.CANCELED:
                            // TODO
                            break;
                        case SplitInstallSessionStatus.DOWNLOADED:
                            Toast.makeText(SplashActivity.this, " Downloaded but not installed", Toast.LENGTH_LONG).show();

                            // TODO
                            break;
                        case SplitInstallSessionStatus.PENDING:
                            // TODO
                            break;
                        case SplitInstallSessionStatus.FAILED:
                            // TODO
                            setContentView(R.layout.activity_splash);
                            break;
                        case SplitInstallSessionStatus.DOWNLOADING:
                            setContentView(R.layout.activity_splash);
                            break;
                    }
                }
            }
        };


        splitInstallManager.registerListener(listener);

        splitInstallManager.startInstall(request)
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                    }
                })
                .addOnSuccessListener(new OnSuccessListener<Integer>() {
                    @Override
                    public void onSuccess(Integer sessionId) {
                        sessionID = sessionId;
                    }
                });

我只是在检查是否安装了动态功能。如果已安装,那么我将 contentView 设置为动态功能的 com.package.B 中存在的布局。

【问题讨论】:

    标签: java android dynamic lottie


    【解决方案1】:

    如果您在本地进行测试,onDemand 模块将不会通过 PlayCore API 加载。

    通常,在您可以从 onDemand 模块访问代码/资源之前,您必须确保在 attachBaseContext 中调用 SplitCompat.install(context) 像这样或类似的:

        override fun attachBaseContext(newBase: Context?) {
            super.attachBaseContext(newBase)
            SplitCompat.install(this)
        }
    

    在查询包管理器时,还要确保应用程序仍然是a

    manager.getResourcesForApplication("com.package.a");
    

    更有可能为给定资源产生结果。

    从用户体验的角度来看,不建议在显示初始屏幕时下载按需模块,然后替换该 Activity 中的视图。

    话虽如此,请检查 catch 块中的异常日志。通过Log.v 而不是e.printStackTrace() 记录它。

    【讨论】:

    • 不,其实我是在 Playstore 上发布后测试的。而且我也没有直接展示动态模块布局。在第一次启动时,会有默认的启动画面,但是当安装了动态部分时,我将显示动态模块中存在的布局。我只是想知道下载动态模块后如何获取布局。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多