[英]Android dynamic feature modules do not work, cannot access resources properly
I am having trouble accessing a resource located in dynamic feature raw folder from my main activity.我无法从我的主要活动访问位于动态功能原始文件夹中的资源。 The installation of the dynamic feature works fine and I can access it immediately with application context but I cannot access it any more after I have restarted my app.
动态功能的安装工作正常,我可以立即使用应用程序上下文访问它,但在我重新启动我的应用程序后我无法再访问它。
The dynamic feature has no classes, only a data.json file.动态特征没有类,只有一个 data.json 文件。
My test procedure:我的测试程序:
My questions:我的问题:
public class ActivityFromBase extends AppCompatActivity {
public void startActivity2() {
Intent intent = new Intent(activity, Activity2.class);
startActivityForResult(intent, 1);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
testAccessResource(this);
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
SplitCompat.install(this);
}
final public static String dynamicResourceName="dynamicResources";
final public static String dynamicResourcePackageName="com.app."+dynamicResourceName;
public static int getRawResourceFromPackage(final Context context, String name, String packageName) {
return context.getResources().getIdentifier(name, "raw", packageName);
}
static public int testAccessResource(final Context context) {
String name="data";
int fromApplicationContext=getRawResourceFromPackage(context.getApplicationContext(), name, dynamicResourcePackageName);
int fromContext=getRawResourceFromPackage(context, name, resourceIDWithContext.context.getPackageName()+"."+dynamicResourceName);
int fromNewContext=0;
int fromNewContext2=0;
int fromNewContext3=0;
int fromNewContext4=0;
int fromNewContext5=0;
try {
Context newContext = context.createPackageContext(context.getPackageName(), 0);
fromNewContext=getRawResourceFromPackage(newContext, name, context.getPackageName()+"."+dynamicResourceName);
Context newContext2 = context.getApplicationContext().createPackageContext(context.getApplicationContext().getPackageName(), 0);
fromNewContext2=Tools.getRawResourceFromPackage(newContext2, name, context.getApplicationContext().getPackageName()+"."+Tools.dynamicResourceName);
fromNewContext3=Tools.getRawResourceFromPackage(context.getApplicationContext(), name, context.getApplicationContext().getPackageName()+"."+Tools.dynamicResourceName);
fromNewContext4=Tools.getRawResourceFromPackage(context.getApplicationContext(), name, dynamicResourcePackageName);
fromNewContext5=Tools.getRawResourceFromPackage(newContext, name, context.getApplicationContext().getPackageName()+"."+Tools.dynamicResourceName);
} catch (PackageManager.NameNotFoundException e) {
}
String message="fromApplicationContext: "+String.valueOf(fromApplicationContext)+" fromContext: "+String.valueOf(fromContext)+" fromNewContext: "+String.valueOf(fromNewContext)+" fromNewContext2: "+String.valueOf(fromNewContext2)+" fromNewContext3: "+String.valueOf(fromNewContext3)+" fromNewContext4: "+String.valueOf(fromNewContext4)+" fromNewContext5: "+String.valueOf(fromNewContext5);
Log.d("dynamic",message);
}
}
public class Activity2 extends Activity {
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
SplitCompat.install(this);
}
public void runTest() {
testAccessResource(this);
}
public void installDynamicFeature() {
SplitInstallManager splitInstallManager;
splitInstallManager = SplitInstallManagerFactory.create(this);
SplitInstallRequest request =
SplitInstallRequest
.newBuilder()
.addModule(ActivityFromBase.dynamicResourceName)
.build();
SplitInstallStateUpdatedListener listener = state -> {
if (state.status()== SplitInstallSessionStatus.INSTALLED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
SplitInstallHelper.updateAppInfo(this);
}
}
};
splitInstallManager.registerListener(listener);
splitInstallManager
.startInstall(request);
}
}
AndroidManifest of dynamic feature动态特性的AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.app.dynamicresources">
<application android:hasCode="false"/>
<dist:module
dist:instant="false"
dist:title="@string/title_dynamicresources">
<dist:delivery>
<dist:on-demand />
</dist:delivery>
<dist:fusing dist:include="true" />
</dist:module>
</manifest>
AndroidManifest of app应用程序的AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app">
<application
android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
<activity
android:name=".ActivityFromBase"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:exported="true">
<activity
android:name=".Activity2"
android:parentActivityName=".ActivityFromBase"
android:theme="@style/Theme.AppCompat.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.app.ActivityFromBase" />
</activity>
</application>
</manifest>
After dozens of uploads to the internal test track I was able to identify the reason.在将数十次上传到内部测试轨道后,我能够找出原因。 Somehow the AdMob initialization destroys the resource access if it is done too late.
如果 AdMob 初始化完成得太晚,它会以某种方式破坏资源访问。 attachBaseContext is called before onCreate method of the activity so the solution was to do the AdMob initialization there:
attachBaseContext 在活动的 onCreate 方法之前被调用,所以解决方案是在那里进行 AdMob 初始化:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
MobileAds.initialize(this, ...
SplitCompat.install(context);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.