Synchronized与Lock锁的区别

楔子

最近一直都比较忙,没有时间写博客了。今天项目终于灰度了,可以有时间写写博客,看看文章了!!!╮(╯▽╰)╭

今天要写的主题是Java的基础知识,Synchronized和Lock锁的区别!!!

区别

1、ReentrantLock拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候等特性。

查看更多

Android构建神器之Gradle

什么是Gradle

Gradle构建生命周期

构建阶段

初始化阶段

配置阶段

执行阶段

Groovy小demo

Gradle实战

Android Gradle实战

Android-分析并优化首页启动时间

前言

随着app项目越来越大,功能业务越来越多,需要我们初始化的模块也越来越多,application中onCreate和attachBaseContext方法越来越臃肿,最直接导致的是我们app启动时间大大增加

性能分析

首页HomeActivity

执行命令

am start -W com.wuba/com.wuba.home.activity.HomeActivity

输出结果:

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.wuba/.home.activity.HomeActivity }
Status: ok
Activity: com.wuba/.home.activity.HomeActivity
ThisTime: 1858
TotalTime: 1858
WaitTime: 1925
Complete

启动页面LaunchActivity

执行命令

adb shell start -W com.wuba/com.wuba.activity.launch.LaunchActivity

输出结果

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.wuba/.activity.launch.LaunchActivity }
Status: ok
Activity: com.wuba/.activity.launch.LaunchActivity
ThisTime: 1134
TotalTime: 1134
WaitTime: 1147
Complete

启动场景

冷启动

也就是我们常说的冷启动,这时候你的应用程序的进程是没有创建的. 这也是大部分应用的使用场景.用户在桌面上点击你应用的 icon 之后,首先要创建进程,然后才启动 MainActivity.这时候adb shell am start -w packagename/xxxActivity 返回的结果,就是标准的应用程序的启动时间(注意 Android 5.0 之前的手机是没有 WaitTime 这个值的):

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.wuba/.home.activity.HomeActivity }
Status: ok
Activity: com.wuba/.home.activity.HomeActivity
ThisTime: 1858
TotalTime: 1858
WaitTime: 1925
Complete

热启动

就是应用不是第一次启动,如果是你按Back键,并没有将应用进程杀掉的话,那么执行上述命令就会快一些,因为不用创建进程了,只需要启动一个Activity即可。这也就是我们说的应用热启动。

参考资料

http://www.open-open.com/lib/view/open1451570355573.html

知乎·计算apk的启动时间

ReactNative开发Android端遇到的一些坑总结

优化查询加载大数量的本地相册图片

优化查询加载大数量的本地相册图片

一、概述

讲解优化查询相册图片之前,我们先来看下PM提出的需求,PM的需求很简单,就是要做一个类似微信的本地相册图片查询控件,主要包含两个两部分:

  • 进入图片选择页面就要显示出手机中所有的照片,包括系统相册图片和其他目录下的所有图片,并按照时间倒叙排列
  • 切换相册功能,切换相册页面列出手机中所有的图片目录列表,并且显示出每个目录下所有的图片个数以及封面图片

这两个需求看似简单,实则隐藏着一系列的性能优化问题。在做优化之前,我们调研了一些其他比较出名的app在加载大数量图片的性能表现(gif录制的不够清晰,但展示问题已经够了):

微信

微信的图片查询速度还是非常快的,基本上进入图片选择页面,相册数据就已经查出来了,包括各个图片目录下图片的个数和封面图片的url,这个体验还是比较好的

新浪微博

相比较微信来说,新浪微博做的体验就比较差了,进入图片选择页面后,先是黑屏然后是白屏,连个进度条都没有,让用户以为app死掉了,等过一段时间才显示出来,这个体验较差

QQ

QQ一上来是加载的最近100张照片,这个速度非常快,但是进入Camera相册(有5000多张)后,有一个进度条等待,我体验了下,等待的时间还是比较长的,这个体验比新浪微博稍微好点,比微信差

闲鱼

闲鱼是做的最烂的一个,一上来是卡死四五秒,然后是黑屏两三秒,最后才显示出来

查看更多

React-Native-Android热更新

简介

为什么要有热更新,热更新的好处是什么?

推荐JS开发工具

  1. Sublime
  2. WebStorm
  3. 其他

native增量更新方案

参考SmartAppUpdates

React-Native移植-Android

简介

参考链接:
Integrating with Existing Apps

由于公司业务需要,部分模块需要将native代码转移到react-native,并且由于是已有项目,所以我这里单独把react-native移植到项目来,移植的过程中遇到了一些问题,这里也记录了下。

网上的一些教程资料都不是很全,而且一些关键的步骤说的都不是很详细,这里我们从零开始。

还有就是环境配置这里不讲了,都是很基础的东西!

新建一个Android项目

这里我们新建一个ReactNativeProject,初始化目录结构如下:

引入React-Native

在你的app目录下的build.gradle加入react-native依赖,我加入的是最新版本的0.20.1

compile 'com.facebook.react:react-native:0.20.1'

然后在AndroidManifest.xml加入访问网络权限,当然一般已经项目都有这个权限,如果有这一步可以忽略

<uses-permission android:name="android.permission.INTERNET" />

为了让项目支持调试RN,需要在AndroidManifest.xml里面加入RN的DevSettingsActivity,如下:

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

这样真机晃动手机或者点击Menu菜单就会打开相关的调试页面,如图下所示:

这里部署完后,还有一个坑,就是React-Native对编译版本和最小编译版本都有要求,它需要app的build.gradle文件的compileSdkVersion为23,minSdkVersion为16,因为我们项目要求最低版本为15甚至更低,这里需要在app的AndroidManifest.xml加入

<uses-sdk tools:overrideLibrary="com.facebook.react" />

查看更多

apk打包流程梳理

简介

一些初学Android的开发者可能只知道写完项目,然后点击AndroidStudio中的run按钮就可以把项目运行到手机或者模拟器上,而一个apk是怎么从编译打包到最后签名安装到手机上的原理不知道,这里就带领大家理解一下内部的原理

简单build流程

首先,我们看下官网介绍Building and Running Overview,官网给了我们一张非常简单的编译、打包、apk生成内容以及签名的图片,因为官网必须得用vpn才能访问,这里我就直接下载下来了,简单build图片如下:

图片大体介绍了从Project到运行到设备或者模拟器的一个大体流程,我们也从中看到一个完整的apk包含如下内容:一个或多个dex文件、resources.arsc、未编译的资源文件以及AndroidManifest.xml文件等等

详细打包流程

官网给了我们一张非常清晰的打包流程图:

下面这幅图就是整个Android应用(不包含NDK部分)的构建编译框架详细流程说明(来源于官方):

打包步骤

总体打包步骤我们可以概括以下七步:

  1. 通过aapt打包资源文件,生成R.java和resources.arsc
  2. 处理aidl文件,生成对应的java接口文件
  3. 编译项目工程源代码,生成.class文件
  4. Dex命令处理,将第三步生成的.class文件和第三方的库一起生成classes.dex文件
  5. 通过apkbuilder工具将aapt生成的resources.arsc、classes.dex(可能多个)、其他的资源一块打包生成apk文件
  6. 通过Jarsigner对第五步生成的apk进行debug或者release签名,只有签名完的apk才能进行安装
  7. 通过aipalign对签名后的apk进行对其处理,使apk中所有资源文件距离文件起始偏移为4字节的整数倍,从而在通过内存映射访问apk文件时会更快

其实还应该有最后一步,那就是通过adb install命令将生成的apk安装到设备或者模拟器上

接口和抽象类区别

接口和抽象类有什么区别?

你选择使用接口和抽象类的依据是什么?

理解抽象

abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。 abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于 abstract class和interface的选择显得比较随意。

其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。

语法定义理解

  1. 抽象类

    abstract class Demo {    
    
        abstract void method1();    
    
        abstract void method2();    
    
        …    
    
    }    
    
  2. 接口

    interface Demo {    
    
        void method1();    
    
        void method2();    
    
        …    
    
    }    
    

在abstract class方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,Demo只能够有静态的 不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊 形式的abstract class。

查看更多

Java反转单链表实战

算法是程序代码的灵魂!!!Java反转单链表这种算法一般会在面试中遇到,尤其是一些大公司!!!这里就来通过Java代码实战来讲解下实现反转的两种方法。

  1. 递归
  2. 普通遍历

这里介绍的两种方法都很常见,递归在算法里面非常常见!!

首先,我们要定义一个Node节点类:

public class Node{
    int value;
    Node nextNode;
    public Node(int value, Node nextNode) {
        super();
        this.value = value;
        this.nextNode = nextNode;
    }
}

因为是单链表,这里只有nextNode和当前节点的值。

查看更多