最近在研究Android动态加载APK技术,偶有小得,共享一下,欢迎交流。
首先是Android 动态加载已安装的APK
被调用工程TestB:
其工程已添加了字符串、颜色和图片资源,这里不写了,读者可自行添加。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class TestBActivity extends Activity{       /** Called when the activity is first created. */       @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.main);           Button button=(Button)findViewById(R.id.button1);           button.setOnClickListener(new OnClickListener() {               @Override               public void onClick(View v) {                   // TODO Auto-generated method stub                   Toast.makeText(TestBActivity.this, "this is testB", Toast.LENGTH_SHORT).show();               }           });       }   } | 
接着把TestB打包为TestB.apk,放到sdcard的根目录。
调用工程TestA:
首先应该是安装apk文件:
| 1 2 3 4 5 6 7 8 9 10 | protected void InstallAPK(String apkname) {           // TODO Auto-generated method stub           //代码安装           String fileName = Environment.getExternalStorageDirectory() + "/"+apkname;            Intent intent = new Intent(Intent.ACTION_VIEW);            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   //       intent.setDataAndType(Uri.parse("file://"+fileName), "application/vnd.android.package-archive");             intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");            TestAActivity.this.startActivityForResult(intent, 1); | 
但是安装之前是不是要先检测一下TestB.apk是否已安装呢:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | protected boolean checkInstall(String pak) {       // TODO Auto-generated method stub       boolean install=false;       PackageManager pm=getPackageManager();       try {           PackageInfo info=pm.getPackageInfo(pak,1);           if (info!=null&&info.activities.length>0) {               install=true;           }       } catch (NameNotFoundException e) {           // TODO Auto-generated catch block           e.printStackTrace();       }       return install;   }   | 
如果未安装,便调用InstallAPK(String apkname)安装,如果已安装便可代码获取其资源:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | private void getRes(String pak){       if (checkInstall(pak)) {       try {               Context ctxTestB = getTestContext(pak);               Resources res = ctxTestB.getResources();               // 获取字符串string               String hello = res.getString(getId("string", "hello", pak));               ((TextView) findViewById(R.id.testb_string)).setText(hello);               // 获取图片Drawable               Drawable drawable = res.getDrawable(getId("drawable", "testb",pak));               ((ImageView) findViewById(R.id.testb_drawable)).setImageDrawable(drawable);               // 获取颜色值               int color = res.getColor(getId("color", "white",pak));               ((TextView) findViewById(R.id.testb_color)).setBackgroundColor(color);               // 获取布局文件               View view = getView(ctxTestB, getId("layout", "main",pak));               LinearLayout layout = (LinearLayout) findViewById(R.id.testb_layout);               layout.addView(view);       } catch (NameNotFoundException e) {       e.printStackTrace();   }}   }    //获取资源对应的编号   private int getId(String name, String type,String pak) {       return testb.getIdentifier(name, type, pak);   }    // 获取视图   public View getView(Context ctx, int id) {       return ((LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(id,null);   }    //获取TestB的Context   private Context getTestContext(String pak) throws NameNotFoundException {       return createPackageContext(pak,Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);   } | 
接下来再来看看怎么使用Intent组件启动被调用工程:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | protected void startAPK(String pak) {       // TODO Auto-generated method stub       //代码启动       try {                         //pak=PACKAGE_TEST_B+".TestBActivity"           Context ctxTestB = getTestContext(PACKAGE_TEST_B);           Class cls = ctxTestB.getClassLoader().loadClass(pak);           TestAActivity.this.startActivity(new Intent(ctxTestB, cls));       } catch (ClassNotFoundException e) {           e.printStackTrace();       } catch (NameNotFoundException e) {           // TODO Auto-generated catch block           e.printStackTrace();       }   } | 
以下为扩展内容:
比如加上网络下载apk文件功能,然后再安装,这里使用的是URL通信协议,用HttpURLConnection类,面向的是应用层:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | protected File downLoadFile(String httpUrl) {                       // TODO Auto-generated method stub           String filename="down_TestB.apk";           File file=new File(Environment.getExternalStorageDirectory() + "/"+filename);                       try {                               URL url = new URL(httpUrl);                               try {                                       HttpURLConnection conn = (HttpURLConnection) url                                                       .openConnection();                                       InputStream is = conn.getInputStream();                                       FileOutputStream fos = new FileOutputStream(file);                                       byte[] buf = new byte[256];                                       conn.connect();                                       int count = 0;                                       if (conn.getResponseCode()==200) {                                              while ((count=is.read(buf))>0) {                                                  fos.write(buf, 0, count);                                           }                                       }                                       conn.disconnect();                                       fos.close();                                       is.close();                               } catch (IOException e) {                                       // TODO Auto-generated catch block                                       e.printStackTrace();                               }                       } catch (MalformedURLException e) {                               // TODO Auto-generated catch block                               e.printStackTrace();                       }                       return file;               } | 
 
  
