Android深入四大组件(三)Service的绑定过程

本文首发于微信公众号「刘望舒」

VeA93D.jpg
相关文章
Android深入理解四大组件系列

前言

我们可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service,建议阅读此篇文章前请阅读Android深入四大组件(二)Service的启动过程这篇文章,知识点重叠的部分,本篇文章将不再赘述。

查看更多

分享到 评论

Android深入四大组件(二)Service的启动过程

本文首发于微信公众号「后厂村刘皇叔」

前言

此前我用较长的篇幅来介绍Android应用程序的启动过程(根Activity的启动过程),这一篇我们接着来分析Service的启动过程。建议阅读此篇文章前,请先阅读Android深入四大组件(一)应用程序启动过程(前篇)Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章。

查看更多

分享到 评论

Java虚拟机(一)结构原理与运行时数据区域

前言

本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关知识,Java虚拟机也并不是三言两语能够介绍完的,因此开了Java虚拟机系列,这一篇文章我们来学习Java虚拟机的结构原理与运行时数据区域。

查看更多

分享到 评论

设计模式(十五)状态模式

本文首发于微信公众号「刘望舒」

相关文章
设计模式系列

前言

建议在阅读本文前先阅读设计模式(十一)策略模式这篇文章,虽说状态模式和策略模式的结构几乎是相同的,但是它们所解决的问题是不同的,读完这两篇文章你就会有了答案。

查看更多

分享到 评论

我的独立博客:http://liuwangshu.cn上线了

关于独立博客

我的独立博客地址为:http://liuwangshu.cn
虽然有了独立博客,但我还会继续在CSDN、简书中持续更新我的文章。独立博客收入了我精选的70多篇文章,在电脑和手机上都有着良好的阅读体验,欢迎大家关注。

查看更多

分享到 评论

Android深入四大组件(一)应用程序启动过程(后篇)

本文首发于微信公众号「刘望舒」

1.ActivityManageService到ApplicationThread的调用流程

AMS的startActivity方法中return了startActivityAsUser方法:

查看更多

分享到 评论

Android深入四大组件(一)应用程序启动过程(前篇)

本文首发于微信公众号「后厂村刘皇叔」

VekBAP.png

前言

在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。

查看更多

分享到 评论

Android绘制优化(二)布局优化

本文首发于微信公众号「后厂村码农」

相关文章
Android性能优化系列

前言

我们知道一个界面的测量和绘制是通过递归来完成的,减少布局的层数就会减少测量和绘制的时间,从而性能就会得到提升。当然这只是布局优化的一方面,那么如何来进行布局的分析和优化呢?本篇文章会给你一个满意的答案。

查看更多

分享到 评论

Android应用程序进程启动过程(后篇)

本文首发于微信公众号「刘望舒」

前言

在前篇中我们讲到了Android应用程序进程启动过程,这一篇我们来讲遗留的知识点:在应用程序进程创建过程中会启动Binder线程池以及在应用程序进程启动后会创建消息循环。

查看更多

分享到 评论

Android应用程序进程启动过程(前篇)

本文首发于微信公众号「刘望舒」

前言

在此前我讲过Android系统的启动流程,系统启动后,我们就比较关心应用程序是如何启动的,这一篇我们来一起学习Android7.0 应用程序进程启动过程,需要注意的是“应用程序进程启动过程”,而不是应用程序启动过程。关于应用程序启动过程,我会在后续系列的文章中讲到。希望阅读这篇文章前先阅读本文列出的相关文章,要不你一脸蒙蔽,就别怪我了。

查看更多

分享到 评论

Android绘制优化(一)绘制性能分析

本文首发于微信公众号「后厂村码农」

相关文章
Android性能优化系列

前言

一个优秀的应用不仅仅是要有吸引人的功能和交互,同时在性能上也有很高的要求。运行Android系统的手机,虽然配置在不断的提升,但仍旧无法和PC相比,无法做到PC那样拥有超大的内存以及高性能的CPU,因此在开发Android应用程序时也不可能无限制的使用CPU和内存,如果对CPU和内存使用不当也会造成应用的卡顿和内存溢出等问题。因此,应用的性能优化对于开发人员有着更高的要求。Android性能优化分为很多种,比较常用的有绘制优化、内存优化、耗电优化和稳定性优化等,这个系列我们就来学习性能优化中的绘制优化。

查看更多

分享到 评论

设计模式(十四)中介者模式

本文首发于微信公众号「刘望舒」

相关文章
设计模式系列

前言

写了很多篇设计模式的文章,才发现没有讲关于设计模式的分类,那么这一篇就补上这一内容,顺便带来中介者模式的讲解。并与此前讲过的代理模式和外观模式做对比。

查看更多

分享到 评论

算法(三)初等排序后篇[选择和冒泡排序]

本文首发于微信公众号「后厂村码农」

1.选择排序

根据上一篇文章讲到的插入排序和希尔排序,我们把选择排序的数组也分为已排序部分和未排序部分。

图解选择排序

在用图来讲解选择排序之前,我们要先了解选择排序的规则。
选择排序的规则
就是重复执行以下的处理:
1.找出未排序部分最小值的位置min。
2.将min位置的元素与未排序部分的起始元素做对比,如果顺序错误则将它们进行就交换。

以数组a={5,4,8,7,9,3,1}为例,我们对其进行从小到大排序,排序过程如下图所示。

VmVXw9.png
首先我们找到未排序部分最小的值a[6]=1和未排序的起始元素a[0]=5相比较,发现a[6]的值更小,则将两个数进行交换,以此类推。
VmVjoR.png

最终得到的结果为a={1,3,4,5,7,8,9}

实现选择排序

接下来要实现插入排序,针对下图来定义变量。
VmVqL4.png

如上图所示,i为循环变量,代表未排序部分的开头元素; j为循环变量,用来遍历未排序部分找出最小值min。
接下来我们用代码来实现选择排序,如下所示。

public class SelectionSort {
    public static void main(String[] args) {
        int a[] = {5, 4, 8, 7, 9, 3, 1};
        ArrayUtils.printArray(a);
        int b[] = selection(a);
        ArrayUtils.printArray(b);
    }

    public static int[] selection(int[] a) {
        int i, j, min, v;
        int n = a.length;
        for (i = 0; i < n; i++) {
        //每次将未排序部分的首元素下标赋值给下标min
            min = i;
            //得到未排序部分的最小值的下标并赋值给min
            for (j = i+1; j < n; j++) {
                if (a[j] < a[min]) {
                    min = j;
                }
            }
            v = a[i];
            a[i] = a[min];
            a[min] = v;
        }
        return a;
    }
}

其中负责打印数组的ArrayUtils类如下所示。

public class ArrayUtils {
    public static void printArray(int[] array) {
        System.out.print("{");
        int len=array.length;
        for (int i = 0; i < len; i++) {
            System.out.print(array[i]);
            if (i < len - 1) {
                System.out.print(", ");
            }
        }
        System.out.println("}");
    }
}

输出结果为:
{5, 4, 8, 7, 9, 3, 1}
{1, 3, 4, 5, 7, 8, 9}

选择排序复杂度

假设数据总数为n,则为了搜索未排序部分最小的的值需要(n-1)+(n-2)+(n-3)+……+1次比较,也就是n²/2+n/2次比较,因此时间复杂度为O(n²)。同样的,此前讲过的插入排序和冒泡排序的时间复杂度也是O(n²)。它们的区别就是:不含flag的冒泡算法和选择排序并不依赖于比较运算的次数,不受输入数据的影响,而插入算法却依赖于比较运算的次数,处理某些数据时会具有很高的效率。

2.冒泡排序

冒泡排序应该是开发者最容易理解的排序算法,它的基本思想就是每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。需要进行排序的元素则向水中的气泡一样慢慢的移向水面。

图解冒泡排序

与选择排序一样,需要进行冒泡排序的数组也分为已排序部分和未排序部分。
冒泡排序的规则为:从数组末尾开始依次比较相邻的两个元素,如果大小关系相反则交换位置,直到数组中不再有顺序相反的相邻元素。

我们对数组 a={5,3,2,4,1} 进行从小到大排序,排序过程如下所示。
第一轮排序:

VmVOeJ.png

我们将数组末尾的a[4]的值和a[3]的值进行对比,发现a[4]的值比a[3]的值小,则将它们交换,再接着对剩下的相邻的两个元素进行对比和交换,最终得到的结果为a={1,5,3,2,4},已排序的部分的元素为1。

第二轮排序:

VmVxF1.png

首先对比a[3]和a[4]的值,发现a[3]的值比a[4]的值小,则不需要进行排序。最终得到的结果为a={1,2,5,3,4},已排序部分的元素为1、2。

第三轮排序:
VmZSW6.png

经过第三轮排序,已排序部分的元素为1、2、3。

第四轮排序:

VmVzJx.png

经过四轮排序我们最终得到的结果为a={1,2,3,4,5}

实现冒泡排序

实现插入排序时,我们要先定义两个变量,i为循环变量,表示未排序部分的开头元素,从数组开头向末尾移动。j也为循环变量,用于对未排序部分中相邻元素两两比较,从数组的末尾n-1开始减小到 i 结束(i=1)。

VmZ9SK.png

代码实现如下所示。

public class BubbleSort {
    public static void main(String[] args) {
        int a[] = {5, 3, 2, 4, 1};
        ArrayUtils.printArray(a);
        int b[] = bubble(a);
        ArrayUtils.printArray(b);
    }
    public static int[] bubble(int[] a) {
        int i, j, v;
        int n = a.length;
        for (i = 0; i < n - 1; i++) {
            for (j = n - 1; j > i; j--) {
                if (a[j] < a[j - 1]) {
                    v = a[j];
                    a[j] = a[j - 1];
                    a[j - 1] = v;
                }
            }
        }
        return a;
    }
}

其中ArrayUtils的printArray方法此前讲过,这里就不再给出,打印结果为:
{5, 3, 2, 4, 1}
{1, 2, 3, 4, 5}

当然有的同学不喜欢这样从数组的末尾开始比较,这里给出常规的冒泡,如下所示。

public class BubbleSort2 {
    public static void main(String[] args) {
        int a[] = {5, 3, 2, 4, 1};
        ArrayUtils.printArray(a);
        int b[] = bubble(a);
        ArrayUtils.printArray(b);
    }
    public static int[] bubble(int[] a) {
        int i, j, v;
        int n = a.length;
        for (i = 0; i < n - 1; i++) {
            for (j = 0; j < n - i - 1; j++) {
                if (a[j] > a[j + 1]) {
                    v = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = v;
                }
            }
        }
        return a;
    }
}

冒泡排序的复杂度

最坏的情况下,冒泡排序对未排序部分的相邻元素进行了(n-1)+(n-2)+(n-3)+……+1次比较,也就是n²/2-n/2次比较,根据推导大O阶的规则我们得出冒泡排序的时间复杂度为O(n²)。

github源码

分享到 评论

Android系统启动流程(四)Launcher启动过程与系统启动流程

本文首发于微信公众号「刘望舒」

前言

此前的文章我们学习了init进程、Zygote进程和SyetemServer进程的启动过程,这一篇文章我们就来学习Android系统启动流程的最后一步:Launcher的启动流程,并结合本系列的前三篇文章的内容来讲解Android系统启动流程。建议读这篇文章前要通读本系列的前三篇文章,否则你可能不会理解我在讲什么。

查看更多

分享到 评论

算法(二)初等排序前篇[插入和希尔排序]

本文首发于微信公众号「后厂村码农」

前言

排序是算法的基础,排序有很多种方法,有些方法实现起来很简单,但是效率较差,我们可以将这些排序的方法称之为初等排序。这篇文章我们就来学习初等排序中的插入排序和希尔排序。

查看更多

分享到 评论

Android系统启动流程(三)解析SyetemServer进程启动过程

本文首发于微信公众号「刘望舒」

前言

上一篇我们学习了Zygote进程,并且知道Zygote进程启动了SyetemServer进程,那么这一篇我们就来学习Android7.0版本的SyetemServer进程的启动过程。

查看更多

分享到 评论