安卓编程技巧总结(3) 进程与线程处理


  1. 多进程
安卓支持多进程
好处:
-- 减轻APP内存压力;
-- 逻辑相对独立;例如我们可以使Service在独立进程中执行数据计算处理操作,
   处理的结果与主进程通过AIDL通信;
缺点:
-- 首次进入新启动进程的页面时会有延时的现象,如闪屏,一般与Activity 的主题有关;
-- Application 被实例化多次,应考虑其中定义的一些参数是否合理;
   可以在Application中加进程的逻辑判断,在指定的进程中,才初始化对应的数据;  
-- 多进程间通过 SharedPreferences 共享数据时不稳定;
-- APP退出操作不能完全退出,仅退出了当前进程;
  1. 线程的管理
单个线程的创建,比较简单,通用的方法是:实现Runnable接口或者继承Thread类。
但是,这种方式创建的线程,不应该任意使用,应对创建的线程做好管理,
例如:线程缓存、顺序执行、最大并发数等等;

Java提供的一套线程管理的方案:线程池(ThreadPoolExecutor),
关于线程池的使用,Java默认给封装了几个类型,都可以通过Executors直接创建,例如:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
线程池类型:
FixedThreadPool:固定大小的线程池,可解决最大并发数;
SingleThreadPool:单一线程池,可保证线程一个个执行;
CachedThreadPool:缓存线程池,减少了线程的重用性,提高了性能;
ScheduledThreadPool:定时线程池,可定时、延时执行线程;

具体的使用,我们需要根据特定场合,如果使用不当,也会有一些问题:
FixedThreadPool 和 SingleThreadPool : 
允许的请求队列长度过大,可能会堆积大量的请求,从而导致 OOM;
CachedThreadPool 和 ScheduledThreadPool : 
允许的创建线程数量过大,可能会创建大量的线程,从而导致 OOM。

其实,我们还可以通过new ThreadPoolExecutor(),构建自定义的线程池,自己定义的规则,
如何管控线程,自己也清楚,如下:
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();//最大可用的处理器数量
int KEEP_ALIVE_TIME = 1;//  设置线程存活时间(setKeepAliveTime),确保空闲时线程能被释放
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();//线程队列,存放线程
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,NUMBER_OF_CORES*2, 
KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT,taskQueue, new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());

Android中和线程、线程池相关的还有IntentService、AsyncTask、SurfaceView等,此处不再累述;
  1. 线程使用
子线程中不能直接更新界面,更新界面必须在UI线程中进行。

线程间通信Handler,可以自定义接口回调,也可使用EventBus等代替,
各有优缺点,自己根据情况合理使用。

注意:Handler不要通过 Msg 传递大的对象,会导致内存问题。
  1. 线程锁
作用:确保数据同步执行,保证数据的原子性。
线程锁类型,按使用方式可分为:可重入锁、不可重入锁(自旋锁)、公平锁、非公平锁、读写锁。
显示锁用Lock来定义、内置锁用syschronized
Lock接口,主要定义方法:
lock();
unLock();
tryLock();
lockInterrupt();
newCondition();

可重入锁(已获得某对象、代码库的锁后,可直接访问它的其他同步方法):
syschronized、reentraintLock
-- synchronized编码较简单;
-- ReentrantLock功能更丰富一些,如时间锁等候,可中断锁等候,锁投票等,还可以定义多个条件;
-- ReentrantLock必须在finally中释放锁;
-- ReentrantLock 的性能比synchronized会好点;

自旋锁(自旋锁可以使线程在没有取得锁的时候,不被挂起,而转去执行一个空循环,
(即所谓的自旋,就是自己执行空循环),若在若干个空循环后,线程如果可以获得锁,则继续执行。)

公平锁(排队竞争)
-- 构造ReentrantLock (true)时,表示为公平锁;
非公平锁(非排队竞争)
-- 构造ReentrantLock ()时,表示为非公平锁;

读写锁
允许多个读操作同时进行,但每次只允许一个写操作。
读写锁是一种性能优化的策略。
--ReentrantReadWriteLock
  1. 进程使用
-- 官方不推荐 在多 进 程 之 间 用 SharedPreferences 共 享数 据 ;
-- 尽量减少不同 APP 之间的进程间通信及拉起行为。拉起导致占用系统资源,影响用户体验。
  1. 进程间通信时注意URI传递
7.0之后,安卓安全性提高,APP之间传递文件路径时,应注意适配,
防止出现FileUriExposedException异常;

具体请参考:
https://www.jianshu.com/p/bec4497c2a63

7.带返回值的异步任务Callable<T>

其实,除Runnable接口外,Callable泛型参数化接口也可以实现异步任务。

Runnable与Callable不同点:
1. Runnable不返回任务执行结果,Callable可返回任务执行结果;
2. Callable在任务无法计算结果时抛出异常,而Runnable不能;
3. Runnable任务可直接由Thread的start方法或ExecutorService的submit方法去执行;
Callable只通过ExecutorService的submit方法去执行;

ExecutorService的submit方法返回FutureTask对象,要获得Callable接口返回的执行结果,
需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;
当不调用此方法时,主线程不会阻塞!

Callable示例:查找文件包含某关键字总个数:每个文件启动一个线程查找关键字

public class FileSearchTask {
    public static void main(String[] args) throws ExecutionException, 
InterruptedException {
        String path = args[0];
        String keyword = args[1];
        int c = 0;
        File[] files = new File(path).listFiles();
        ArrayList<Future<Integer>> rs = new ArrayList<>();
        for(File file: files){  //每个文件启动一个task去查找
            MatchCount count = new MatchCount();
            count.file = file;
            count.keyword = keyword;
            FutureTask<Integer> task = new FutureTask(count);
            rs.add(task); //将任务返回的结果添加到集合中
            Thread thread = new Thread(task);
            thread.start();
        }

        for(Future<Integer> f: rs){
            c += f.get(); //迭代返回结果并累加,会阻塞线程,直到结果返回;
        }
        System.out.println("包含关键字的总文件数为:" + c);
    }
}

class  MatchCount implements Callable<Integer>{
    public File file;
    public String keyword;
    private  Integer count = 0;

    public Integer call() throws Exception {   //call封装线程所需做的任务
        if(search(file))
              count ++;
        return count;
    }

    public boolean search(File file){
        boolean founded = false;
        try(Scanner scanner = new Scanner(new FileInputStream(file))){
            while(!founded && scanner.hasNextLine()){
                if (scanner.nextLine().contains(keyword))
                    founded = true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return  founded;
    }
}

第一篇: 安卓编程技巧总结(1) 资源与UI布局处理

https://www.jianshu.com/p/ff97b15d5c9d

第二篇: 安卓编程技巧总结(2) 基础组件开发

https://www.jianshu.com/p/b05752377887

第三篇:安卓编程技巧总结(3) 进程与线程处理

https://www.jianshu.com/p/7d05c8a368bd

第四篇:安卓编程技巧总结(4) 数据文件处理

https://www.jianshu.com/p/0515df3b697d

第五篇:安卓编程技巧总结(5) 图片处理

https://www.jianshu.com/p/76690b2ba310

第六篇:安卓编程技巧总结(6) APP安全分析

https://www.jianshu.com/p/4347ff392122

第七篇:安卓编程技巧总结(7) 性能检测代码分析

https://www.jianshu.com/p/687f3c641408

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容