同一个so是否可以被多个classloader加载
答案:1 悬赏:0 手机版
解决时间 2021-01-30 18:40
- 提问者网友:謫仙
- 2021-01-30 02:48
同一个so是否可以被多个classloader加载
最佳答案
- 五星知识达人网友:雪起风沙痕
- 2021-01-30 03:47
新建一个andorid工程(我比较懒,刚才已经就是使用的andorid工程),然后把testdex.jar复制到assets目录下面,来看看我的工程目录吧。
然后贴出FileUtil.java的代码package com.demo.utile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.content.Context;
import android.os.Environment;
public class FileUtile {
public static void CopyAssertJarToFile(Context context, String filename,
String des) {
try {
File file = new File(Environment.getExternalStorageDirectory()
.toString() + File.separator + des);
if (file.exists()) {
return;
}
InputStream inputStream = context.getAssets().open(filename);
file.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte buffer[] = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != 0) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.close();
fileOutputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这个类主要的作用就是把我们的jar相当于解压到一个目录下面。我这里是解压到外置设备上的其实这样做的安全性并不高,但是为了方便我就这样做了,建议是解压到包目录下面。记住别忘了给应用加权限!!!!!文件读写权限!!!! 最后我们来看看Activity里面的代码package com.demo.activity;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import com.demo.utile.FileUtile;
import dalvik.system.DexClassLoader;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
FileUtile.CopyAssertJarToFile(this, "testdex.jar", "testdex.jar");
File file = new File(Environment.getExternalStorageDirectory()
.toString() + File.separator + "testdex.jar");
final File optimizedDexOutputPath = getDir("temp", Context.MODE_PRIVATE);
DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null,
getClassLoader());
try {
Class iclass = classLoader.loadClass("com.demo.dex.IClass");
Constructor istructor = iclass.getConstructor(Context.class);
//利用反射原理去调用
Method method = iclass.getMethod("call", null);
String data = (String) method.invoke(istructor.newInstance(this), null);
System.out.println(data);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其实这样调用还有一点要注意的是我感觉这样做每次都要去调用反射,总给我感觉来说不太友好,那么这里我有给出了下面一种写法,这种写法最主要的地方是,要获得Iinterface这个接口,把Iinterface.java这个文件复制到你的工程里面,记得包名相同,调用的时候我们可以这样来调用它。Class iclass = classLoader.loadClass("com.demo.dex.IClass");
Constructor istructor = iclass.getConstructor(Context.class);
Iinterface iinterface = (Iinterface) istructor.newInstance(this);
String data = iinterface.getData();
iinterface.call();
Toast.makeText(this, data, 0).show();转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
然后贴出FileUtil.java的代码package com.demo.utile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.content.Context;
import android.os.Environment;
public class FileUtile {
public static void CopyAssertJarToFile(Context context, String filename,
String des) {
try {
File file = new File(Environment.getExternalStorageDirectory()
.toString() + File.separator + des);
if (file.exists()) {
return;
}
InputStream inputStream = context.getAssets().open(filename);
file.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte buffer[] = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != 0) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.close();
fileOutputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这个类主要的作用就是把我们的jar相当于解压到一个目录下面。我这里是解压到外置设备上的其实这样做的安全性并不高,但是为了方便我就这样做了,建议是解压到包目录下面。记住别忘了给应用加权限!!!!!文件读写权限!!!! 最后我们来看看Activity里面的代码package com.demo.activity;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import com.demo.utile.FileUtile;
import dalvik.system.DexClassLoader;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
FileUtile.CopyAssertJarToFile(this, "testdex.jar", "testdex.jar");
File file = new File(Environment.getExternalStorageDirectory()
.toString() + File.separator + "testdex.jar");
final File optimizedDexOutputPath = getDir("temp", Context.MODE_PRIVATE);
DexClassLoader classLoader = new DexClassLoader(file.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null,
getClassLoader());
try {
Class iclass = classLoader.loadClass("com.demo.dex.IClass");
Constructor istructor = iclass.getConstructor(Context.class);
//利用反射原理去调用
Method method = iclass.getMethod("call", null);
String data = (String) method.invoke(istructor.newInstance(this), null);
System.out.println(data);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其实这样调用还有一点要注意的是我感觉这样做每次都要去调用反射,总给我感觉来说不太友好,那么这里我有给出了下面一种写法,这种写法最主要的地方是,要获得Iinterface这个接口,把Iinterface.java这个文件复制到你的工程里面,记得包名相同,调用的时候我们可以这样来调用它。Class iclass = classLoader.loadClass("com.demo.dex.IClass");
Constructor istructor = iclass.getConstructor(Context.class);
Iinterface iinterface = (Iinterface) istructor.newInstance(this);
String data = iinterface.getData();
iinterface.call();
Toast.makeText(this, data, 0).show();转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯