經過FlutterLoader加載更新libapp.so文件完成動態化--代碼編寫(基於1.22以上版本,適用純Flutter應用和混合應用)

國際慣例先上狗圖,以防被打,看不懂的能夠先看第一篇文章的源碼解讀。android

一.經過FlutterLoader加載更新libapp.so文件完成動態化--源碼解析

1.1 拷貝ApplicationInfoLoader代碼,重載load方法

final class KCApplicationInfoLoader {
    ....
     @NonNull
    public static FlutterApplicationInfo load(@NonNull Context applicationContext,String path) {
        ApplicationInfo appInfo = getApplicationInfo(applicationContext);
        // Prior to API 23, cleartext traffic is allowed.
        boolean clearTextPermitted = true;
        if (android.os.Build.VERSION.SDK_INT >= 23) {
            clearTextPermitted = NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted();
        }

        return new FlutterApplicationInfo(
                path,
                getString(appInfo.metaData, PUBLIC_VM_SNAPSHOT_DATA_KEY),
                getString(appInfo.metaData, PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY),
                getString(appInfo.metaData, PUBLIC_FLUTTER_ASSETS_DIR_KEY),
                getNetworkPolicy(appInfo, applicationContext),
                appInfo.nativeLibraryDir,
                clearTextPermitted);
    }
}
複製代碼

1.2 繼承FlutterLoader,重寫ensureInitializationComplete方法

public class KCFlutterLoader extends FlutterLoader {
    private static final String TAG = "KCFlutterLoader";
    private static KCFlutterLoader flutterLoaderInstance=new KCFlutterLoader();
    public static KCFlutterLoader getInstance() {
        return flutterLoaderInstance;
   }
    @Override
    public void startInitialization(@NonNull Context applicationContext) {
        Log.d(TAG,"KCFlutterLoader===startInitialization");
        super.startInitialization(applicationContext);
    }
    @Override
    public void ensureInitializationComplete(@NonNull Context applicationContext, @Nullable String[] args) {

        Log.d(TAG,"KCFlutterLoader===ensureInitializationComplete");
        File file=new File(applicationContext.getFilesDir(),"libappfix.so");
        if(file.exists()){
            String name=file.getAbsolutePath();
            FlutterApplicationInfo flutterApplicationInfo = KCApplicationInfoLoader.load(applicationContext, name);
            try {
                Class FlutterLoaderClass = Class.forName("io.flutter.embedding.engine.loader.FlutterLoader");
                Field nameField = FlutterLoaderClass.getDeclaredField("flutterApplicationInfo");
                nameField.setAccessible(true);
                nameField.set(this,flutterApplicationInfo);
               
                Field initialized = FlutterLoaderClass.getDeclaredField("initialized");
                initialized.setAccessible(true);
                // 這裏是調試方便默認設置爲false,在真實狀況下,這個變量應該保存在本地sp中,跟隨so的變化而改變。避免重複加載,影響性能
                initialized.set(this,false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        super.ensureInitializationComplete(applicationContext, args);
    }
}
複製代碼

1.3 注入自定義的FlutterLoader

1.3.1 純flutter應用注入

public class MyApplication extends FlutterApplication {
    public static Application  application;
    @Override
    public void onCreate() {
        //修改FlutterLoader
        FlutterInjector flutterInjector = FlutterInjector.instance();
        try {
            Class FlutterInjectorClass = Class.forName("io.flutter.FlutterInjector");
            Field nameField = FlutterInjectorClass.getDeclaredField("flutterLoader");
            nameField.setAccessible(true);
            nameField.set(flutterInjector,KCFlutterLoader.getInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onCreate();
        application=this;
    }
}
複製代碼

1.3.2 混合flutter應用注入

在混合應用中注入自定義的FlutterLoader相對簡單,只須要在FlutterEngine初始化時將自定義FlutterLoader實例傳遞進去就行了:安全

FlutterEngine flutterEngine =new FlutterEngine(context, KCFlutterLoader.getInstance(),new FlutterJNI())
複製代碼

1.4 libapp.so的注意

1.libapp.so爲了安全性最好下載在應用的file目錄下

2.libapp.so在下載完成後能夠經過生成md5值,確保文件安全性和完整性

3.若是更新的libapp.so初始化完成後,爲了不重複加載,須要設置FlutterLoader中的initialized爲true(initialized變量保存到本地sp,跟隨so的變化而改變)。
複製代碼

一.經過FlutterLoader加載更新libapp.so文件完成動態化--源碼解析

到這裏就完成動態化方案的代碼編寫,至於說蘋果的動態化方案,就算有大家敢用嗎...,懂得都懂。謝謝了你們,劃了這麼多水,最後求個贊QAQ。

image

相關文章
相關標籤/搜索