Android开发注意事项

本文作为个人笔记,吸取采纳各位大神的精华,作为个人开发注意事项,仅在CSDN保存。

1.Context的用法 

举例:单利模式(非线程安全)

public class Singleton {
    private static Singleton instance;
    private Context mContext;

    private Singleton(Context context) {
        this.mContext = context;
    }

    public static Singleton getInstance(Context context) {
        if (instance == null) {
            instance = new Singleton(context);
        }
        return instance;
    }
}

这是一个非线程安全的单例模式,instance作为静态对象,其生命周期要长于普通的对象,其中也包含Activity,假如Activity A去getInstance获得instance对象,传入this,常驻内存的Singleton保存了你传入的Activity A对象,并一直持有,即使Activity被销毁掉,但因为它的引用还存在于一个Singleton中,就不可能被GC掉,这样就导致了内存泄漏。

注意事项:

一般Context造成的内存泄漏,几乎都是当Context销毁的时候,却因为被引用导致销毁失败,而Application的Context对象可以理解为随着进程存在的,所以我们总结出使用Context的正确姿势:
1:当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
2:不要让生命周期长于Activity的对象持有到Activity的引用。
3:尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。

2.Class加载过程之自定义ClassLoader

/**
 * 自定义文件类加载器
 */
public class FileSystemClassLoader extends ClassLoader {

    private String rootDir;

    public FileSystemClassLoader(String rootDir){
        this.rootDir = rootDir;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> loadedClass = findLoadedClass(name);
        if(null != loadedClass){
            return loadedClass;
        }else{
            ClassLoader classLoader = this.getParent();
            try{
                loadedClass = classLoader.loadClass(name);
            }catch (ClassNotFoundException e){
                e.printStackTrace();
            }
            if(null != loadedClass){
                return loadedClass;
            }else{
                byte[] classData = getClassData(name);
                if(classData == null){
                    throw new ClassNotFoundException();
                }else {
                    loadedClass = defineClass(name,classData,0,classData.length);
                }
            }
        }
        return loadedClass;
    }

    private byte[] getClassData(String name){
        String path = rootDir+"/"+name.replace('.','/')+".class";
        InputStream is = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            is = new FileInputStream(path);
            byte[] bytes = new byte[1024];
            int temp = 0;
            while ((temp = is.read(bytes)) != -1){
                baos.write(bytes,0,temp);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if(baos != null){
                    baos.close();
                }
                if(is != null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

definclass()

把字节码转化为Class

findClass()

  • 根据名称或位置加载.class字节码,然后使用defineClass
  • 通常由子类去实现

loadClass()

  • findLoadedClass(String) 调用这个方法,查看这个Class是否已经别加载

  • 如果没有被加载,继续往下走,查看父类加载器,递归调用loadClass()

  • 如果父类加载器是null,说明是启动类加载器,查找对应的Class

  • 如果都没有找到,就调用findClass(String)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值