Shadow icon indicating copy to clipboard operation
Shadow copied to clipboard

flutter 混编打包成的插件包,flutter 下面的assets本地图片显示不了

Open longrenzhut opened this issue 4 years ago • 37 comments

flutter 混编打包成的插件包,flutter 下面的assets本地图片显示不了,正常运行混编的项目能显示出来,打包成插件的显示不出来,其他的功能正常

longrenzhut avatar Jun 28 '21 09:06 longrenzhut

可以fork一下然后修改source sample,复现一下问题。这样就很容易debug了。

shifujun avatar Jun 28 '21 09:06 shifujun

已经fork 了麻烦帮我看下

longrenzhut avatar Jun 30 '21 11:06 longrenzhut

有时间帮我看看

longrenzhut avatar Jul 02 '21 00:07 longrenzhut

你那个分支改动代码量太大了,看不到重点。你先说一下是Flutter中的dart代码获取不到assets,还是Android的Java代码获取不到assets?获取不到的演示代码在你的分支中是哪行?

shifujun avatar Jul 02 '21 03:07 shifujun

crm/crm/.android/include_flutter.groovy这个文件找不到,编不过。你要不还是重新做个最小改动的复现吧。或者你能基于Flutter的sample指出哪里在shadow下会工作不正常,我也可以直接去看看调用关系。

shifujun avatar Jul 02 '21 04:07 shifujun

嗯嗯,这个我提交没上去,flutter 代码找不到assets

longrenzhut avatar Jul 03 '21 02:07 longrenzhut

那个android 被过滤提交了,没提交上去,现在应该有了

longrenzhut avatar Jul 03 '21 02:07 longrenzhut

代码我没怎么改动,就插件里面提交了flutter demo

longrenzhut avatar Jul 03 '21 02:07 longrenzhut

应该是Flutter的这个代码的问题。

    AssetManager assetManager;
    try {
      assetManager = context.createPackageContext(context.getPackageName(), 0).getAssets();
    } catch (NameNotFoundException e) {
      assetManager = context.getAssets();
    }

https://github.com/flutter/engine/blob/11fde578d53cd4f24abbeff4f151fc7f1a9e8c3f/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java#L281-L286

这里插件和宿主的PackageName是一样的,通过createPackageContext方法问系统创建Context,只能拿到正常安装的app的Context。所以它就拿到宿主的assets了。看这个代码,你可以通过override FlutterActivitygetPackageName方法,使它返回一个造成NameNotFoundException的名字,然后就可以正常拿到 FlutterActivity的assets了。

Shadow可以在ShadowContext里override这个createPackageContext方法来自动支持。但是这个需要假设插件中的代码使用宿主的packageName时都是想创建自己的Context。

shifujun avatar Jul 05 '21 04:07 shifujun

你改过试了没,可以吗,通过override FlutterActivity的getPackageName方法 抛出异常崩溃

longrenzhut avatar Jul 05 '21 06:07 longrenzhut

我没试过。你debug一下这个assetManager是不是宿主的就知道是不是这里的问题了。抛出的异常不是NameNotFoundException的话,你还可以override ShadowContext的createPackageContext方法,返回this。

shifujun avatar Jul 05 '21 06:07 shifujun

抛出的异常是NameNotFoundException,override ShadowContext的createPackageContext方法 在哪里处理,是不是在 PluginDefaultProxyActivity PluginSingleInstance1ProxyActivity PluginSingleTask1ProxyActivity 里面覆盖?

longrenzhut avatar Jul 05 '21 06:07 longrenzhut

插件里的Activity都是继承自ShadowContext的。你可以先确定一下context.createPackageContext的context是不是你的FlutterActivity。然后override那个类的createPackageContext就行了。

也可以直接修改: https://github.com/Tencent/Shadow/blob/master/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java

shifujun avatar Jul 05 '21 06:07 shifujun

大佬,还是不行,可能我搞错了,能不能帮我调试下

longrenzhut avatar Jul 05 '21 06:07 longrenzhut

大佬,还是不行,可能我搞错了,能不能帮我调试下

longrenzhut avatar Jul 05 '21 06:07 longrenzhut

不行是有Crash吗?先把Crash堆栈贴出来我看看。

shifujun avatar Jul 05 '21 06:07 shifujun

Caused by: java.lang.RuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.zhongcai.crm at io.flutter.embedding.engine.loader.FlutterLoader.ensureInitializationComplete(FlutterLoader.java:283) at io.flutter.embedding.engine.FlutterEngine.(FlutterEngine.java:317) at io.flutter.embedding.engine.FlutterEngine.(FlutterEngine.java:260) at io.flutter.embedding.engine.FlutterEngine.(FlutterEngine.java:240) at io.flutter.embedding.engine.FlutterEngine.(FlutterEngine.java:160) at io.flutter.embedding.engine.FlutterEngine.(FlutterEngine.java:151) at com.tencent.shadow.sample.plugin.FlutterHelper.init(FlutterHelper.java:15) at com.tencent.shadow.sample.plugin.MainActivity.onCreate(MainActivity.java:42) at android.app.Activity.performCreate(Activity.java:6698) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2623) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2731)  at android.app.ActivityThread.-wrap12(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1482)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6161)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)  Caused by: android.content.pm.PackageManager$NameNotFoundException: com.zhongcai.crm at android.app.ApplicationPackageManager.getApplicationInfoAsUser(ApplicationPackageManager.java:351) at android.app.ApplicationPackageManager.getApplicationInfo(ApplicationPackageManager.java:333) at io.flutter.embedding.engine.loader.FlutterLoader.ensureInitializationComplete(FlutterLoader.java:250)

longrenzhut avatar Jul 05 '21 07:07 longrenzhut

看起就是FlutterEngine前面那个catch (NameNotFoundException e) 没什么用嘛,后面它还是去getApplicationInfo了。

你那就不要override getPackageName了,直接override createPackageContext方法返回this吧。严谨一点就判断传进来的包名和getPackageName返回值一样就return this。

shifujun avatar Jul 05 '21 07:07 shifujun

嗯嗯,那我试试,在flutterActivivty 重写下createPackageContext return this

longrenzhut avatar Jul 05 '21 07:07 longrenzhut

打包成功进入了,本地图片还是没有显示出来 package com.tencent.shadow.sample.plugin;

import android.content.Context; import android.content.pm.PackageManager; import android.os.Bundle; import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.tencent.shadow.sample.plugin.statusbar.StatusBarCompat;

import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngineCache; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel;

public class FlutterAppActivity extends FlutterActivity {

public static CachedEngineIntentBuilder withCachedEngine(@NonNull String cachedEngineId) {
    return new CachedEngineIntentBuilder(FlutterAppActivity.class, cachedEngineId);
}

String url;
@Override
protected void onCreate(Bundle savedInstanceState) {

    String id = getIntent().getStringExtra("id");
     url = "main?"+ (!TextUtils.isEmpty(id) ? id : "id=5837") + "&platform=android";

    super.onCreate(savedInstanceState);
    StatusBarCompat.setStatusBarColor(getWindow(),
            getResources().getColor(android.R.color.transparent), true,true);


    initChannel("crm");
}

// @Override // public String getInitialRoute() { // return TextUtils.isEmpty(url) ? super.getInitialRoute(): url; // }

@Override
public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException {
    return this;
}

// @Override // public String getPackageName() { // return "com.zhongcai.crm"; // }

@Override
protected void onDestroy() {
    super.onDestroy();

// FlutterHelper.onDestroy("crm"); }

private void initChannel(String engineId) {
    FlutterEngine engine =  FlutterEngineCache.getInstance().get(engineId);
    MethodChannel nativeChannel = new MethodChannel(engine.getDartExecutor(), engineId);
    nativeChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
            switch (methodCall.method) {
                case "close":
                    finish();
                    // 跳转原生页面

// Intent jumpToNativeIntent = new Intent(getActivity(), NativeActivity.class); // jumpToNativeIntent.putExtra("name", (String) methodCall.argument("name")); // //因为写的demo所以直接采用了魔法数字 方便文章中看的直观 // startActivityForResult(jumpToNativeIntent, 1001); break; default: result.notImplemented(); break; } } }); } }

longrenzhut avatar Jul 05 '21 07:07 longrenzhut

https://github.com/flutter/flutter/blob/5c6605f70b945cff98670e64d0d6fc1417126da7/examples/image_list/lib/main.dart#L105

是这种加载assets吧?我可以调试下这个官方的example。

shifujun avatar Jul 05 '21 07:07 shifujun

嗯嗯,好像没加载assets下面的 使用的是Image.asset

longrenzhut avatar Jul 05 '21 07:07 longrenzhut

那你引用下你的代码中显示图片的代码是哪行。

shifujun avatar Jul 05 '21 07:07 shifujun

我写的demo里面BottomBarWidget 里面 然后调用ImageHelper 中buildImage方法 ,里面用的image.asset 方法加载本地图片

longrenzhut avatar Jul 05 '21 07:07 longrenzhut

我还是自己写了一下: https://github.com/shifujun/Shadow/commits/issue553 4个提交。

https://github.com/shifujun/Shadow/commit/4a5874e500f41bff1b043818aefd0ab957414687 是dart代码使用Image.asset显示图片。

最后一个提交前,sample-host运行效果: image

最后一个提交把createPackageContextreturn this了,就正常了: image

shifujun avatar Jul 05 '21 08:07 shifujun

嗯嗯,我看看

longrenzhut avatar Jul 05 '21 08:07 longrenzhut

你启动方式和我不一样 你是直接打开flutterAcitivy?

longrenzhut avatar Jul 06 '21 01:07 longrenzhut

你可以在我代码的基础上改一下,看看能不能复现问题。我已经把flutter代码的aar上库了,不用再编译flutter部分了。 跟这个问题相关的只有传给FlutterEngine的context是哪个context的问题。

shifujun avatar Jul 06 '21 01:07 shifujun

报错 Execution failed for task ':plugin-normal-apk:checkDebugAarMetadata'.

Could not resolve all files for configuration ':plugin-normal-apk:debugRuntimeClasspath'. Could not find com.example.my_flutter:flutter_debug:1.0. Searched in the following locations: - https://mirrors.tencent.com/nexus/repository/maven-public/com/example/my_flutter/flutter_debug/1.0/flutter_debug-1.0.pom - https://maven.pkg.github.com/tencent/shadow/com/example/my_flutter/flutter_debug/1.0/flutter_debug-1.0.pom - https://repo.maven.apache.org/maven2/com/example/my_flutter/flutter_debug/1.0/flutter_debug-1.0.pom - https://dl.google.com/dl/android/maven2/com/example/my_flutter/flutter_debug/1.0/flutter_debug-1.0.pom Required by: project :plugin-normal-apk > project :plugin-main-lib

Possible solution:

  • Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html

arr包总是导入不进去,这个有其他配置导致的吗 String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com" repositories { maven { url '../my_flutter_build_repo' } maven { url "$storageUrl/download.flutter.io" } }

longrenzhut avatar Jul 06 '21 03:07 longrenzhut

不是maven的sample。直接在根目录执行./gradlew :sample-host:assembleDebug.

你要自己接入到其他项目里的话,可以参考:https://flutter.dev/docs/development/add-to-app/android/project-setup#manual-integration

shifujun avatar Jul 06 '21 04:07 shifujun