Project introduction:
speed-tools is a dynamic deployment apk hot update framework and plug-in development framework based on agent mode.
The name speed-tools refers mainly to the rapid iterative development toolset.
Functions and characteristics:
1. Support Android Version 2.3 or above
2. Supporting direct invocation of R file resources
3. No launch call during development
4. apk does not need to install direct calls
5. Proxy mode is less intrusive to code
6. Easy to use, just inherit simple classes.
Usage method
Adding dependencies:
compile 'com.liyihangjson:speed_tools:1.0.3'
First look at the project structure:
lib_speed_tools: plug-in core function library
module_host_main: Host Engineering Master Project, responsible for loading and deploying apk
module_client_one: Test business apk 1
module_client_two: Test business apk 2
lib_img_utils: Test the imageloader picture frame
Note: To use speed tools, you just need to rely on lib_speed_tools, and then start configuring the plug-in steps:
First create the business logic class in module_client_one: TestClass.java
/** * by liyihang */ public class TestClass extends SpeedBaseInterfaceImp { private Activity activity; @Override public void onCreate(Bundle savedInstanceState, final Activity activity) { this.activity=activity; activity.setContentView(R.layout.activity_client_main); activity.findViewById(R.id.jump).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SpeedUtils.goActivity(activity,"first_apk", "two_class"); } }); ImageView imageView= (ImageView) activity.findViewById(R.id.img_view); imageView.setVisibility(View.VISIBLE); ImgUtils.getInstance(activity).showImg("http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg", imageView); } }
Business activity proxy class in SpeedBaseInterfaceImp business component, which implements the main lifecycle approach, is equivalent to the component activity class.
Then create the hock class and create only one in each business component: ClientMainActivity.java
public class ClientMainActivity extends SpeedClientBaseActivity { @Override public SpeedBaseInterface getProxyBase() { return new TestClass(); } }
This class is the only one in the component, and its function is to use hock for independent testing.
Next, configure Android Manifest. XML for the configuration component
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/SpeedTheme"> <!--Must set root_class--> <meta-data android:name="root_class" android:value="com.example.clientdome.TestClass" /> <meta-data android:name="two_class" android:value="com.example.clientdome.TwoClass" /> <activity android:name=".ClientMainActivity" android:theme="@style/SpeedTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!--Component intent--> <intent-filter> <data android:scheme="speed_tools" android:host="sijienet.com" android:path="/find_class"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application>
The component intends to write to death all the time, and root_class is the business class that uses the com.example.clientdome.TestClass for configuration after the call dies. This completes the business component configuration.
Next, configure the host project module_host_main;
Create the unique hock class for the host project: ApkActivity.java
/** * by liyihang * blog http://sijienet.com/ */ public class ApkActivity extends SpeedHostBaseActivity { @Override public String getApkKeyName() { return HostMainActivity.FIRST_APK_KEY; } @Override public String getClassTag() { return null; } }
The whole host project can create a class, the user is hock activity; then it takes some time to create an open page apk when it first loads. It is very suitable to put the open page waiting for the page.
HostMainActivity.java
/** * by liyihang * blog http://sijienet.com/ */ public class HostMainActivity extends AppCompatActivity implements Runnable,Handler.Callback, View.OnClickListener { public static final String FIRST_APK_KEY="first_apk"; public static final String TWO_APK_KEY="other_apk"; private Handler handler; private TextView showFont; private ProgressBar progressBar; private Button openOneApk; private Button openTwoApk; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_host_main); showFont= (TextView) findViewById(R.id.show_font); progressBar= (ProgressBar) findViewById(R.id.progressbar); openOneApk= (Button) findViewById(R.id.open_one_apk); openTwoApk= (Button) findViewById(R.id.open_two_apk); handler=new Handler(this); new Thread(this).start(); } @Override public void run() { String s = "module_client_one-release.apk"; String dexOutPath="dex_output2"; File nativeApkPath = SpeedUtils.getNativeApkPath(getApplicationContext(), s); SpeedApkManager.getInstance().loadApk(FIRST_APK_KEY, nativeApkPath.getAbsolutePath(), dexOutPath, this); String s2 = "module_client_two-release.apk"; String dexOutPath2="dex_output3"; File nativeApkPath1 = SpeedUtils.getNativeApkPath(getApplicationContext(), s2); SpeedApkManager.getInstance().loadApk(TWO_APK_KEY, nativeApkPath1.getAbsolutePath(), dexOutPath2, this); handler.sendEmptyMessage(0x78); } @Override public boolean handleMessage(Message message) { showFont.setText("Currently the primary host apk\n Plug-in unit apk Complete"); progressBar.setVisibility(View.GONE); openOneApk.setVisibility(View.VISIBLE); openTwoApk.setVisibility(View.VISIBLE); openOneApk.setOnClickListener(this); openTwoApk.setOnClickListener(this); return false; } @Override public void onClick(View v) { if (v.getId()==R.id.open_one_apk) { SpeedUtils.goActivity(this, FIRST_APK_KEY, null); } if (v.getId()==R.id.open_two_apk) { SpeedUtils.goActivity(this, TWO_APK_KEY, null); } } }
Loading the apk core code is:
String s = "module_client_one-release.apk"; String dexOutPath="dex_output2"; File nativeApkPath = SpeedUtils.getNativeApkPath(getApplicationContext(), s); SpeedApkManager.getInstance().loadApk(FIRST_APK_KEY, nativeApkPath.getAbsolutePath(), dexOutPath, this);
Business apk s are placed in the assets directory. Finally, configure the AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.hostproject"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/SpeedTheme"> <!--start-up activity Load apk--> <activity android:name=".HostMainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--assembly hack--> <activity android:name=".ApkActivity" android:label="@string/app_name" android:theme="@style/SpeedTheme" > <intent-filter> <data android:scheme="speed_tools" android:host="sijienet.com" android:path="/find_class"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> </manifest>
So all configurations end and plug-in is implemented.
github: https://github.com/jasonliyihang/speed_tools
Author: Yihang