International convention first on the dog figure, in case of being hit, can not understand the first article to read the source code.

Update libapp.so file via FlutterLoader to complete dynamic — source parsing

1.1 Copy the ApplicationInfoLoader code and reload the load method

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); }}Copy the code

1.2 succession FlutterLoader, rewrite ensureInitializationComplete method

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); The default is false. In real cases, this variable should be stored in the local sp and changed with the change of so. Initialized. Set (this,false); } catch (Exception e) { e.printStackTrace(); } } super.ensureInitializationComplete(applicationContext, args); }}Copy the code

1.3 Injecting the user-defined FlutterLoader

1.3.1 Pure FLUTTER application injection

public class MyApplication extends FlutterApplication { public static Application application; @override public void onCreate() {FlutterLoader FlutterInjector FlutterInjector = flutterinject.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; }}Copy the code

1.3.2 Hybrid Flutter application injection

Injecting a custom FlutterLoader into a hybrid application is relatively easy, just pass in the custom FlutterLoader instance when the FlutterEngine is initialized:

FlutterEngine flutterEngine =new FlutterEngine(context, KCFlutterLoader.getInstance(),new FlutterJNI())
Copy the code

1.4 libapp.so

Libapp. so is best downloaded in the application file directory for security. Libapp. so can generate md5 values after downloading to ensure file security and integrity. If the updated libapp.so is initialized, you need to set Initialized to true in the FlutterLoader to avoid repeated loading (initialized variable is saved to the local SP and changes with so).Copy the code

Update libapp.so file via FlutterLoader to complete dynamic — source parsing

Here to complete the dynamic program code, as for the apple dynamic program, even if you dare to use it… I understand everything. Thanks for all that water and a thumbs up QAQ at the end.