文章出处:http://blog.csdn.net/zhang957411207/article/details/7581070


最近在研究Android动态加载APK技术,偶有小得,共享一下,欢迎交流。

首先是Android 动态加载已安装的APK


被调用工程TestB:

其工程已添加了字符串、颜色和图片资源,这里不写了,读者可自行添加。

public class TestBActivity extends Activity{/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);Button button=(Button)findViewById(R.id.button1);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubToast.makeText(TestBActivity.this, "this is testB", Toast.LENGTH_SHORT).show();}});}}

接着把TestB打包为TestB.apk,放到sdcard的根目录。

调用工程TestA:

首先应该是安装apk文件:

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是否已安装呢:

protected boolean checkInstall(String pak) {// TODO Auto-generated method stubboolean 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 blocke.printStackTrace();}return install;}

如果未安装,便调用InstallAPK(String apkname)安装,如果已安装便可代码获取其资源:

private void getRes(String pak){if (checkInstall(pak)) {try {Context ctxTestB = getTestContext(pak);Resources res = ctxTestB.getResources();// 获取字符串stringString hello = res.getString(getId("string", "hello", pak));((TextView) findViewById(R.id.testb_string)).setText(hello);// 获取图片DrawableDrawable 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的Contextprivate Context getTestContext(String pak) throws NameNotFoundException {return createPackageContext(pak,Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);}

接下来再来看看怎么使用Intent组件启动被调用工程:

protected void startAPK(String pak) {// TODO Auto-generated method stub//代码启动try {                       //pak=PACKAGE_TEST_B+".TestBActivity"ContextctxTestB = 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 blocke.printStackTrace();}}

以下为扩展内容:

比如加上网络下载apk文件功能,然后再安装,这里使用的是URL通信协议,用HttpURLConnection类,面向的是应用层:

protected File downLoadFile(String httpUrl) {                // TODO Auto-generated method stubString 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;        }

此工程还可扩展,比如获取未安装apk或者已安装apk的版本、图标等资源,和已安装的apk进行版本比较,以确定是否要升级新版本。关于此可以看下我的另一篇博文《Android获取未安装和已安装apk的版本、图标等资源》。

Ok,到此结束!


更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
  3. Android屏幕分辨率正确获取及PX,DPI,DP,SP等的对应关系
  4. Android(安卓)环境搭建
  5. Android(安卓)Wifi模块分析(三)
  6. Android中dispatchDraw分析
  7. Android四大基本组件介绍与生命周期
  8. android 获取唯一标识
  9. android拍照与读取相册

随机推荐

  1. 详细介绍解析Xml四种方法的示例代码
  2. 详细介绍测试几个xml的问题的案例
  3. XML布局文件的代码案例分享
  4. JS读取XML数据的示例代码分享
  5. 具体介绍使用XmlReader读取xml文件的代码
  6. 详解XML中Node和Element区别的示例代码
  7. Xml序列化的图文代码详解
  8. XML学习(三) js保存xml的示例代码分享
  9. XML串行化的示例代码分享
  10. 详细介绍XML操作总结的示例代码