0%

朋友,不是你好就够了

朋友,不是你好就够了

我是大家公认的好人。

五个人坐车,我会主动去坐地铁

一帮朋友吃饭,我会悄悄去结帐

高中好不容易鼓起勇气表白,却被告知,你真的很好,但不适合我

我不好,真的不好,这么好,你怎么不接受我呢

大学时我去了离家很远的地方上学,沈阳工业大学。后来接到了一通电话,竟是她打来的,她说她也选择了沈阳…

开学那天我去接了她,但是少了一种感觉。以前没觉得她皮肤黑啊,现在也觉得略微有点胖了…

后来简单寒暄逛了校园后,我就回自己学校了,从此大学四年再也没见过…

在我大学毕业的时候,又接到了她的电话,她说,高中时要是没拒绝你,现在会不会不这样…

这个问题,我当时沉默了好久,后来说了句,一切都是最好的安排…

我不为做过的决定后悔,不管是自己的还是他人的

我只为遇见更好的她而努力

现在,遇见了

朋友,不是你不够好,而是他人觉得你不好。现在的你,已经是以前最好的你了 永远怀抱期待,明天会来的

西游团队的核心你以为是唐僧麽?

西游团队的核心你以为是唐僧麽?

小时候经常看六小龄童老师演的西游记,长大了才有想法看一看原著,颠覆了很多观念。比如大慈大悲的观世音菩萨,其实是心狠手辣之人,猪八戒加入团队是为了暗杀某人…

首先聊一下主题吧,为什么唐僧不是团队的核心。作为西游的主导者,大唐皇帝御弟,第十世如来坐下弟子转世的金蝉子,怎么算都是队伍的关键吧。其实不然,转世转世,如今也只是一个凡人。大家都记得孙悟空刚逃出五指山遇到老虎那一回吧。唐僧马上准备逃跑,吓得心惊胆战。更别说一路上歪瓜劣枣的妖怪了。书上多处说的是唐僧遇到长得丑的妖怪,吓得跌倒马下,脚不自已。。全凭悟空在旁打气,“师父放心,我能摆平”。唐僧才能勉强淡定。

书中多处也描写到唐僧被抓走后,整日哭哭啼啼,语无伦次。呆子总想散伙,悟空又站出来鼓舞士气,坚定目标…沙僧说二师兄,就听大师兄的吧!

所以综上所述,悟空才是西游团队最核心的一股东。

xUtils3用法

xUtils3用法

转载自:http://blog.csdn.net/smartbetter/article/details/51866792

1.先来认识一下xUtils3

1)xUtils3简介

xUtils是目前功能比较完善的一个Android开源框架,最近又发布了xUtil3.0,在增加新功能的同时又提高了框架的性能,下面来看看官方(https://github.com/wyouflf/xUtils3)对xUtils3的介绍:

xUtils包含了很多实用的android工具;

xUtils支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响;

xUtils 最低兼容Android 4.0 (api level 14);

xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本:

HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略;

支持标准的Cookie策略, 区分domain, path;

事件注解去除不常用的功能, 提高性能;

数据库api简化提高性能, 达到和greenDao一致的性能;

图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转。

2)在我们的项目中快速配置xUtils3

xUtils3的配置十分的简单:

2-1)使用Gradle构建时添加一下依赖即可

compile'org.xutils:xutils:3.3.36'

如果使用eclipse可以点击下面链接下载aar文件, 然后用zip解压,取出jar包和so文件。

Github下载:https://github.com/wyouflf/xUtils3

JCenter下载:http://jcenter.bintray.com/org/xutils/xutils/

Maven下载1:http://central.maven.org/maven2/org/xutils/xutils/

Maven下载2:http://repo1.maven.org/maven2/org/xutils/xutils/

2-2)加入权限



2-3)创建Application

public class MyApp extends Application{

@Override public void onCreate() {

super.onCreate();       

 x.Ext.init(this);       

 x.Ext.setDebug(false);//输出debug日志,开启会影响性能

}}

2-4)在AndroidManifest文件中注册MyApp


xUtils3主要包含注解模块、网络模块、图片模块和数据库模块,下面将做一一说明。

2.xUtils3注解模块的使用

xUtils3注解模块在实际开发中的使用如下:

1)Activity的注解的使用如下:



2)Fragment的注解的使用如下:



3)为按钮设置点击事件

方法必须私有限定,

方法参数形式必须和type对应的Listener接口一致.

注解参数value支持数组: value={id1, id2, id3}



强调:使用注解模块一定要注意初始化视图注解框架。

3.xUtils3网络模块的使用

xUtils3网络模块大大方便了在实际开发中网络模块的开发,xUtils3网络模块大致包括GET请求、POST请求、如何使用其他请求方式、上传文件、下载文件、使用缓存等功能,下面将做一一说明:

1)GET请求


下面我们来看下带有缓存的GET请求,POST请求和其他请求方式类似,后面就不再赘述:

带有缓存的GET请求:

RequestParams params =newRequestParams(url);params.addQueryStringParameter("username","abc");params.addQueryStringParameter("password","123");// 默认缓存存活时间, 单位:毫秒(如果服务器没有返回有效的max-age或Expires则参考)params.setCacheMaxAge(1000*60);x.http().get(params,newCallback.CacheCallback() {privatebooleanhasError =false;privateString result =null;@OverridepublicbooleanonCache(String result) {//得到缓存数据, 缓存过期后不会进入this.result = result;returntrue;//true: 信任缓存数据, 不再发起网络请求; false不信任缓存数据}@OverridepublicvoidonSuccess(String result) {//如果服务返回304或onCache选择了信任缓存,这时result为nullLog.i("JAVA","开始请求");if(result !=null) {this.result = result;        }    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {        hasError =true;        Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();if(exinstanceofHttpException) {//网络错误HttpException httpEx = (HttpException) ex;intresponseCode = httpEx.getCode();            String responseMsg = httpEx.getMessage();            String errorResult = httpEx.getResult();//...}else{//其他错误//...}    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {if(!hasError && result !=null) {//成功获取数据Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();        }    }});


上面onCache方法中需要注意的几点:

a)如果服务端没有返回过期时间,参考params.setCacheMaxAge(maxAge)方法。

b)客户端会根据服务端返回的header中max-age或expires来确定本地缓存是否给onCache方法。如果服务端没有返回max-age或expires,那么缓存将一直保存,除非这里自己定义了返回false,那么xUtils将请求新数据, 来覆盖它。

c)如果信任该缓存返回true,将不再请求网络。返回false继续请求网络,但会在请求头中加上ETag,Last-Modified等信息。如果服务端返回304,则表示数据没有更新,不继续加载数据。

2)POST请求

RequestParamsparams=newRequestParams(url);params.addBodyParameter("username","abc");params.addParameter("password","123");params.addHeader("head","android");//为当前请求添加一个头x.http().post(params,newCallback.CommonCallback() {    @OverridepublicvoidonSuccess(String result) {//解析result}    @OverridepublicvoidonError(Throwable ex, boolean isOnCallback) {    }    @OverridepublicvoidonCancelled(CancelledException cex) {    }    @OverridepublicvoidonFinished() {    }});


3)其他网络请求方式

RequestParams params =newRequestParams(url);params.addParameter("username","abc");x.http().request(HttpMethod.PUT, params,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(String result) {//解析result}@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }});



4)上传文件

String path="/mnt/sdcard/Download/icon.jpg";RequestParams params =newRequestParams(url);params.setMultipart(true);params.addBodyParameter("file",newFile(path));x.http().post(params,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(String result) {    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }});


5)下载文件

这里以下载apk为例进行说明,apk下载完成后,自动调用系统的安装方法。

url ="http://127.0.0.1/server/abc.apk";RequestParams params =newRequestParams(url);//自定义保存路径,Environment.getExternalStorageDirectory():SD卡的根目录params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/myapp/");//自动为文件命名params.setAutoRename(true);x.http().post(params,newCallback.ProgressCallback() {@OverridepublicvoidonSuccess(File result) {//apk下载完成后,调用系统的安装方法Intent intent =newIntent(Intent.ACTION_VIEW);        intent.setDataAndType(Uri.fromFile(result),"application/vnd.android.package-archive");        getActivity().startActivity(intent);    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }//网络请求之前回调@OverridepublicvoidonWaiting() {    }//网络请求开始的时候回调@OverridepublicvoidonStarted() {    }//下载的时候不断回调的方法@OverridepublicvoidonLoading(longtotal,longcurrent,booleanisDownloading) {//当前进度和文件总大小Log.i("JAVA","current:"+ current +",total:"+total);    }});


4.xUtils3图片模块的使用

xUtils3图片模块,重点在于加载图片的4个bind方法,loadDrawable与loadFIle用法和ImageOptions用法,需多加练习。

1)xUtils3 ImageOptions:

//通过ImageOptions.Builder().set方法设置图片的属性ImageOptions imageOptions=newImageOptions.Builder().setFadeIn(true).build();//淡入效果//ImageOptions.Builder()的一些其他属性:.setCircular(true)//设置图片显示为圆形.setSquare(true)//设置图片显示为正方形.setCrop(true).setSize(200,200)//设置大小.setAnimation(animation)//设置动画.setFailureDrawable(Drawable failureDrawable)//设置加载失败的动画.setFailureDrawableId(intfailureDrawable)//以资源id设置加载失败的动画.setLoadingDrawable(Drawable loadingDrawable)//设置加载中的动画.setLoadingDrawableId(intloadingDrawable)//以资源id设置加载中的动画.setIgnoreGif(false)//忽略Gif图片.setParamsBuilder(ParamsBuilder paramsBuilder)//在网络请求中添加一些参数.setRaduis(intraduis)//设置拐角弧度.setUseMemCache(true)//设置使用MemCache,默认true


2)xUtils3 bind方法:

// assets filex.image().bind(imageView,"assets://test.gif", imageOptions);// local filex.image().bind(imageView,newFile("/sdcard/test.gif").toURI().toString(), imageOptions);x.image().bind(imageView,"/sdcard/test.gif", imageOptions);x.image().bind(imageView,"file:///sdcard/test.gif", imageOptions);x.image().bind(imageView,"file:/sdcard/test.gif", imageOptions);x.image().bind(imageView, url, imageOptions,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(Drawable result) {    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }



3)xUtils3 loadDrawable方法:

x.image().loadDrawable(url, imageOptions,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(Drawable result) {        imageView.setImageDrawable(result);    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }});


4)xUtils3 loadFile方法:

当我们通过bind()或者loadDrawable()方法加载了一张图片后,它会保存到本地文件中,那当我需要这张图片时,就可以通过loadFile()方法进行查找。

x.image().loadFile(url,imageOptions,newCallback.CacheCallback(){@OverridepublicbooleanonCache(File result) {//在这里可以做图片另存为等操作Log.i("JAVA","file:"+result.getPath()+result.getName());returntrue;//相信本地缓存返回true}@OverridepublicvoidonSuccess(File result) {    }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) {    }@OverridepublicvoidonCancelled(CancelledException cex) {    }@OverridepublicvoidonFinished() {    }});


4.xUtils3数据库模块的使用

1)初始化配置和创建实体类

首先在项目Application中进行初始化配置DaoConfig(与onCreate方法同级目录下):

/**

* 初始化DaoConfig配置

*/DbManager.DaoConfig daoConfig =newDbManager.DaoConfig()//设置数据库名,默认xutils.db.setDbName("myapp.db")//设置数据库路径,默认存储在app的私有目录.setDbDir(newFile("/mnt/sdcard/"))//设置数据库的版本号.setDbVersion(2)//设置数据库打开的监听.setDbOpenListener(newDbManager.DbOpenListener() {@OverridepublicvoidonDbOpened(DbManager db) {//开启数据库支持多线程操作,提升性能,对写入加速提升巨大db.getDatabase().enableWriteAheadLogging();            }        })//设置数据库更新的监听.setDbUpgradeListener(newDbManager.DbUpgradeListener() {@OverridepublicvoidonUpgrade(DbManager db,intoldVersion,intnewVersion) {            }        })//设置表创建的监听.setTableCreateListener(newDbManager.TableCreateListener() {@OverridepublicvoidonTableCreated(DbManager db, TableEntity table){                Log.i("JAVA","onTableCreated:"+ table.getName());            }        });//设置是否允许事务,默认true//.setAllowTransaction(true)DbManager db = x.getDb(daoConfig);


然后创建数据库表ChildInfo的实体类:

/**

* onCreated = "sql":当第一次创建表需要插入数据时候在此写sql语句

*/@Table(name ="child_info",onCreated ="")publicclassChildInfo{/**

* name = "id":数据库表中的一个字段

* isId = true:是否是主键

* autoGen = true:是否自动增长

* property = "NOT NULL":添加约束

*/@Column(name ="id",isId =true,autoGen =true,property ="NOT NULL")privateintid;@Column(name ="c_name")privateString cName;publicChildInfo(String cName) {this.cName = cName;    }//默认的构造方法必须写出,如果没有,这张表是创建不成功的publicChildInfo() {    }publicintgetId() {returnid;    }publicvoidsetId(intid) {this.id = id;    }publicStringgetcName() {returncName;    }publicvoidsetcName(String cName) {this.cName = cName;    }@OverridepublicStringtoString() {return"ChildInfo{"+"id="+id+",cName='"+cName+'\''+'}';    }}


之后就能进行创建和删除数据库的操作了:

2)创建数据库

//用集合向child_info表中插入多条数据ArrayList childInfos =newArrayList<>();childInfos.add(newChildInfo("zhangsan"));childInfos.add(newChildInfo("lisi"));childInfos.add(newChildInfo("wangwu"));childInfos.add(newChildInfo("zhaoliu"));childInfos.add(newChildInfo("qianqi"));childInfos.add(newChildInfo("sunba"));//db.save()方法不仅可以插入单个对象,还能插入集合db.save(childInfos);


3)删除数据库

db.dropDb();


4)删除表

db.dropTable(ChildInfo.class);


5)新增表中的数据

ChildInfo childInfo =newChildInfo("zhangsan123");db.save(childInfo);


6)删除表中的数据

//第一种写法:db.delete(ChildInfo.class);//child_info表中数据将被全部删除//第二种写法,添加删除条件:WhereBuilder b = WhereBuilder.b();b.and("id",">",2);//构造修改的条件b.and("id","<",4);db.delete(ChildInfo.class, b);


7)修改表中的数据

//第一种写法:ChildInfo first = db.findFirst(ChildInfo.class);first.setcName("zhansan2");db.update(first,"c_name"); //c_name:表中的字段名//第二种写法:WhereBuilder b = WhereBuilder.b();b.and("id","=",first.getId()); //构造修改的条件KeyValue name = new KeyValue("c_name","zhansan3");db.update(ChildInfo.class,b,name);//第三种写法:first.setcName("zhansan4");db.saveOrUpdate(first);


8)查询表中的数据

//查询数据库表中第一条数据ChildInfo first = db.findFirst(ChildInfo.class);Log.i("JAVA",first.toString());//添加查询条件进行查询List all = db.selector(ChildInfo.class).where("id",">",2).and("id","<",4).findAll();for(ChildInfo childInfo :all){    Log.i("JAVA",childInfo.toString());}


5.xUtils3提供的其他一些方法

1)UI异步执行

x.task().run(newRunnable() {@Overridepublicvoidrun() {//异步代码}});


2)UI同步执行

x.task().post(newRunnable() {@Overridepublicvoidrun() {//同步代码}});

一. \Password**

\wifi密码**

bw1308&&

\pin**

123456

tannima

\邮箱**

tanlong@bwic.cn

密码:Ttannima99

先登录阿里云绑定手机修改密码。~

https://qiye.aliyun.com

\confluence&jira账号:**

账号:tanlong

密码:bwtanlong123

confluence地址: http://120.79.4.206:8090

jira地址: http://120.79.4.206:8080

\文档资料:**

confluence培训资料:http://120.79.4.206:8090/x/_oAO

jira培训资料:http://120.79.4.206:8090/x/-IAO

\gerrit账号:**

tanlong

tlong@app6

\服务器IP:192.168.0.200**

账号:tanlong

密码:bw123456

\Ubuntu**

Boom

tannima

Ubuntu2

Tan

\Jenkins**

jenkins网址:http://120.77.175.62:8081
samba:\192.168.0.200\release
谭龙
用户名:tanlong
密码:bwtanlong567

\ftp**

ftp://120.77.175.62/
账号:a100_download
密码:123456

乱码解决

选择时间区域, 设置兼容全球utf-8

公司百度网盘

(手机号是17774990251)

密码:bw1303&&

二. \Git**

代理

1.打开ipaddress.com网站

2.输入GitHub.com或者fastly.net查询IP

3.管理员打开C:\Windows\System32\drivers\etc\hosts

4.199.232.69.194 fastly.net


Q: github.io打不开

A: 按如上配置自己的域名 185.199.109.153 min-secs.github.io

提交

​ git commit

创建新分支,并切到该分支

​ git co -b bugFix

合并

​ git merge bugFix 合并分支到master

​ git rebase master 类似于线性提交

master强制指向head的第三级父提交(不能在当前分支操作当前分支)

​ git branch -f master HEAD~3

撤销

​ git reset 本地

​ git revert 远程

整理提交记录

​ git cherry-pick 知道hash的情况比较方便

​ git rebase -i <HEAD~3>

TAG

​ git tag v1

克隆一个仓库

​ git clone git://

获取远程仓库并合并到本地分支

​ git pull

​ git pull –rebase

上传到远程仓库

​ git push //和push.default文件有关

跟踪远程分支

​ git co -b foo o/master

​ git branch -u o/master foo (原来的跟踪状态不会同步更新)

设置别名

git config –global alias.co “checkout” //使用git co 代替 checkout

图形化界面

gitk –all

覆盖上次提交

git commit –amend

对比

Git log xx

Git log -p xx //比较内容

配置缩写

git config –global alias.st status

查看git地址

git remote show origin

回退到指定commit

git reset –hard commit_id

放弃本地强制和远程一致

git fetch –all

git reset –hard origin/dev

git pull

\遇到的错误**

* git clone错误之”error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054”

A1: git config –global http.sslVerify “false” //验证通过

A2: git config http.postBuffer 524288000 //暂未验证

三. \Gerrit**

配置用户名,邮箱

git config –global user.email “email”

git config –global user.name “username”

查看邮箱

git config user.name

git config user.email

gerrit中配置邮箱

忽略文件

/build

/src/test/

/src/androidTest/

/node_modules/

*.iml

*.json

提交前配置格式化

​ 工程项目仓库,使用 npm init –yes

​ commitizen init cz-conventional-changelog –save –save-exact

git cz //配置提交 git commit –amend //二次提交,未push之前

//提交审核 对应分支 master

git push origin HEAD:refs/for/Platform_Dev

\四.AndroidStudio**

\1. 修改 classpath ‘com.android.tools.build:gradle:3.5.3’

2.gradle-wrapper.properties distributionUrl=https://services.gradle.org/distributions/gradle-5.4.1-all.zip

3.阿里云镜像maven { url ‘http://maven.aliyun.com/nexus/content/groups/public/' }

​ maven { url ‘http://maven.aliyun.com/nexus/content/repositories/jcenter' }

\4. 本地缓存jar包

\c盘/用户/用户名/.gradle/caches/modules-2**

AS各方库,版本号要一致

\5. 定义Live temp生成时间

Setting/Editor/Live Templates

定义变量 $data$ 选择Edit variables date()函数

\项目根目录**

gradlew -q :mediaplayer:dependencies //查看依赖

Q: INSTALL_FAILED_TEST_ONLY: installPackageLI

A: AS3.0以上打包的apk会自动添加test_only=false属性,

android.injected.testOnly=false //gradle.pro中添加

Q: INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113

A: app.gradle

Android{

splits {
abi {
enable true
reset()
include ‘arm64-v8a’ , ‘x86’
universalApk true
}
}

}

导出javadoc

-encoding utf-8 -charset utf-8

四. \访问数据库**

cd /data/user_de/0/com.android.providers.media/databases

cd /data/data/com.android.providers.media/databases

ls

sqlite3 external.db 进入数据库

.tables //列出所有表

.mode column 显示的列会对齐

.header on //显示列名

select * from 表

五. \Ubuntu**

a100-user-debug

Q: 启动Ubuntu黑屏

A: 关闭 3D加速器

Q: git安装失败,git : 依赖: liberror-perl 但无法安装它

A: sudo apt-get update

sudo apt-get install git

Q: 安装vmTools提示空间不足

A: 拷贝到桌面在提取

Q: E: 无法获得锁 /var/lib/apt/lists/lock - open (11 资源临时不可用)

A: sudo rm /var/lib/apt/lists/lock

Q: 正在读取软件包列表… 有错误

A: sudo rm /var/lib/apt/lists/* -vf
sudo apt-get update //耗时较久

Q: E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用

A: sudo rm /var/cache/apt/archives/lock

sudo rm /var/lib/dpkg/lock

sudo rm /var/lib/dpkg/lock-frontend //验证通过

Q: git commit 无法保存

A: ctrl+x 然后按Y

六. \Vim**

  • 查看

vi xx.sh +22 //跳到指定行

  • 删除

当前行 dd

全选ggvG 按d删除

  • 创建文件

touch + xx.tt

  • 查找

/xx 查找某字符, n 向下找

  • 替换

:s/from/to/ 替换当前行第一个

:s/from/to/g 替换当前行所有

  • Mk转bp

out/soong/host/linux-x86/bin

如果没有androidmk 使用m -j blueprint_tools

androidmk android.mk > android.bp

  • 查找

    find prebuilts/sdk/ -name Android.bp|xargs grep “name.*androidx”

七. \Shell**

查看cpu信息

img

adb shell

cat /proc/cpuinfo AArch64对应arm64-v8a

查找文件

busybox find . -name filename

抓取日志

adb pull /data/misc/bwlog/

查看当前占用

Lsof | grep 路径

查看settings 属性

Settings.System.getString(context.getContentResolver(), CustomViewUtils.NAME_BW_THEME_COLOR);

settings get SYSTEM bw_theme_color

查看文件大小

busybox du -h -d 1

模拟mode

./vendor/bin/hw/VehicleSimulateMcu 0 11 7 0 19 4;./vendor/bin/hw/VehicleSimulateMcu 0 11 7 1 19 4;

八. 烧录

文件含义

九. python

使用镜像

pip install xx -i https://pypi.tuna.tsinghua.edu.cn/simple/

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

东风不是你 话里无别他

达达易达达, 踏马当作画,留有坑少许 ,铁树几只花

老泪闻秋悲自橫

Activity官方直译深入理解(完结)

Activity官方直译深入理解(完结)


Activity

一个Activity是用户可以直观交互的东西。所有的activity都聚焦于创建一个窗口,可以通过setcontentview(view)的方式。通常情况下一个activity是全屏显示的,当然也可以设置不同的theme来显示不同的风格,例如windowIsFloating来设置浮动窗口。以下是每个activity必须回调的方法:

Oncreate 在此你可以初始化你的activity。通常情况下你会用布局文件setcontentview的方式来定义此activity。在程序中通过findViewById(int)来和布局中的控件进行交互。

Onpause 当用户离开你的activity时会回调此方法,通常情况下之前用户做的改变行为需在此提交。

在用Context.startActivity()启动之前,需要在AndroidManifest.xml通过<activity>声明。

Activity的生命周期




图片发自简书App

整个过程从Oncreate开始,ondestroy结束。用户可以见到activity时刻从onstart开始到onstop之前。我们可以在onstart里面注册BroadcastReceiver,以便收到广播后修改我们的ui, 在onstop里面取消我们的BroadcastReceiver。用户可以和activity交互的时候从onresume开始直到onpause,一个activity会经常在这两个生命周期切换,所以最好在这两个方法里做轻量级的操作。

你应该在你的子类中回调如下方法,以便在不同的时候处理不同的逻辑。

public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}

Note:如果一个activity的onpause方法不结束的话,当前的或另一个activity的onresume方法不会执行。


Configuration Changes

屏幕翻转,改变语言或者输入设备的改变,都会导致activity销毁。当然,我们可以在manifest.xml里面声明android:configChanges属性,在上述配置改变的时候交给我们自己的activity处理.将回调在这个方法里onConfigurationChanged(Configuration),如果在此方法中有些屏幕配置的改变没有处理到,那么activity还是会被销毁,如果是当前在栈顶的activity则会重建。


Starting Activities and Getting Results

通常情况下我们用startActivity(Intent)来启动一个新的activity,但有时我们想从新的activity结束的时候获取某些数据。比如微信打开相册选择某个图片发给联系人。此时就要用到startActivityForResult(Intent, int),int为请求码,将在稍后介绍。返回的结果将回调在原activity的onActivityResult(int, int, Intent)方法里。不同的int表示不同的情况,如结果返回成功与否。Android系统已帮我们做了定义(RESULT_CANCELED, RESULT_OK)。下面请看示例:见谅,实在不知道怎么在手机上调代码的格式



public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// When the user center presses, let them pick a contact.
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// A contact was picked. Here we will just display it
// to the user.
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}


Permissions

启动一个Activity可能被拒绝,当在manifest里面没声明对应权限的时候。任何一个权限的生命周期(6.0需要特别的权限处理,百度android6.0权限封装)将持续到整个activity结束。


Process Lifecycle

Android系统会尽可能长的保留我们的应用进程,但是当内存不足的时候会移除最老的进程。通常情况下移除进程会和用户交互的activity类型有很大相关,以下列出了四种activity的类型(重要性从高到低):

1.foreground activity

用户正在交互的Activity,如你现在正在浏览的简书。它的进程只有在内存超出预期(由手机设备分配)才会被杀掉,通常来讲设备有责任保留它的进程。

2.visible activity

用户可见但不是foreground activity,比如此时弹出了一个对话框,一般来说不会被杀掉,除非为了保证foreground activity运行。

3.background activity

系统为前两种Activity预留内存会将此activity安全的杀掉。当用户重新返回这个activity时,oncreate方法会被回调,并会在onSaveInstanceState(Bundle)方法保存退出前的状态。

4.empty process

不再持有Activity或者是一个Service or BroadcastReceiver,系统在内存不足时有极大的可能性杀掉,所以我们在用service这种后台服务的时候,需要告诉系统我们的进程需要保留(通常做法是设置前台进程,弹出notification)。


Public method

1.addContentView(View view, ViewGroup.LayoutParams param)

添加一个可添加的布局

2.createPendingResult(int requestCode, Intent data, int flags)

创建一个PendingIntent的对象,并将处理结果返回到onActivityResult(int, int, Intent)。

3.dispatchTouchEvent(MotionEvent ev)

此方法在处理滑动冲突时极为有用,还有一个在子类中常用的方法view.getparent.requestdisallow(true)谁用谁知道。事件分发在很多大牛的文章已经有讲述了,小弟就不献丑了。

4.dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)

打印Activity的状态到指定流

5.enterPictureInPictureMode()

让此Activity进入画中画模式,如果系统允许的话。现在主流直播可能就是此方法的衍生。

6.findViewById(int id)

从XML中解析出view对象

7.finish()

结束当前Activity,有人说此方法是不正常的结束方式,但看官方并无特别说明。

8.finishActivity(int requestCode)

强制关闭通过startActivityForResult(Intent, int)启动的activity。

9.finishAndRemoveTask()

结束一个Task里所有的activity。哟,难道能在主页调这个方法?

10.getApplication()

获取Activity唯一的application。如果是组件化项目不知道这个方式可不可用?

11.getCallingActivity()

超级有用的方法,通常我们做开发的,不知道当前页面是哪个activity,我们可以继承一个baseactivity,然后再回调oncreate的时候打印出当前的类名,这样我们就可以知道哪个页面对应哪个activity了。关于这个郭大神有一篇这个文章,后面我会贴出代码。

12.getCurrentFocus()

获得当前Window聚焦的具体view

13.getFragmentManager()

返回和当前Activity绑定的fragment的fragment manager

14.getIntent()

获得启动此Activity的intent

15.getLayoutInflater()

通过此方法直接解析一个布局成View

16.getReferrer()

谁启动了我?

17.getParentActivityIntent()

18.getRequestedOrientation()

当前请求的屏幕方向,注意用词,请求的,可能没请求成功

19.getSystemService(String name)

根据名字获得不同系统级的服务

20.isDestroyed()

回调的Ondestroy执行了,表示当前activity的实例已经死了

21.isFinishing()

调用Finish()后

22.isImmersive()

是否为沉侵模式,并且不能被通知打断

23.isInMultiWindowMode()

是否为多窗口模式

24.isInPictureInPictureMode()

是否为画中画模式

25.onAttachFragment(Fragment fragment)

回调此方法在Fragment.onAttach()后

26.onAttachedToWindow()

当前Activity的主window是否关联上了windowmanager

27.onBackPressed()

用户按了返回键

28.onKeyDown(int keyCode, KeyEvent event)

当有键被按下的时候,同时所有的子view没有处理的情况会回调

29.onLowMemory()

内存不足时回调,可在此释放一些资源,降低被系统回收的概率

30.onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)

请求的所有权限回调

31.onTouchEvent(MotionEvent event)

触摸事件,当子view没做处理的时候

32.overridePendingTransition(int enterAnim, int exitAnim)

在startActivity(Intent) or finish()后执行activity的切换动画。

33.recreate()

重新创建一个新实例

34.releaseInstance()

通知本地App叫它释放内存

35.runOnUiThread(Runnable action)

运行在UI线程,可在此更新一些界面显示

36.setIntent(Intent newIntent)

更新回调的getintent()

37.setVisible(boolean visible)

当前主Window是否可见



Protected methods

1.onActivityResult(int requestCode, int resultCode, Intent data)

接收启动的Activity结束时返回给它的一系列参数

2.onCreate(Bundle savedInstanceState)

3.onDestroy()

4.onNewIntent(Intent intent)

当启动模式为singleTop,在调用startActivity(Intent)时回调此方法

5.onpaues()

6.onPostCreate(Bundle savedInstanceState)

在onStart() and onRestoreInstanceState(Bundle)后调用,此方法用的少,但存在基友它的道理

7.onPostResume()

在Onresume后调用

8.onUserLeaveHint()

当用户选择进入后台时回调


Activity完

前言:在开发中遇到加载图片的业务时,一不小心就会碰到oom等令人头痛的问题,在低配手机上尤其明显.以下是谷歌官方优化建议

1.避免使用常驻服务

在一个服务使用时再去启动,不用时停止,应用开发推荐使用IntentService

2.合理选择容器

针对HashMap,Android有专门优化过的容器,比如LongSparseArray

3.小心使用抽象

抽象能大大简化子类的代码,但是很多子类并不需要的代码也被放到了类里面,有隐形影响

4.用Protocol Buffers代替序列化数据

谷歌出品,必属精品

5.避免内存流失

常见的有在ondraw里面new obj()

6.移除多余的库

很多时候第三方库能大大节省我们开发代码的时间,但也要考虑到库本身是不是太大并消耗了我们的内存

7.减小apk的体积

使用webp代替png图标,能缩小40%到60%的空间;
使用AS的Analyz分析代码中没用到的资源;
代码混淆也会减小一定的体积

8.依赖注入框架选择Dagger2

谷歌描述的是不会像其他注入框架扫描代码,影响性能

9.谨慎使用外部库

互联网上常用的库,有些可能不是专为手机的操作系统设计的,我们要考量两个方面:本身大小和内存占用情况


针对图片oom,对新手来说使用记住一个公式就可以了
Picasso.with(context).fit().into(view)//Picasso2.5.2版本
这行代码会根据imageview的大小自动适配图片大小

想要深入了解的同学记住一点,就是图片分辨率太大了,想办法压缩图片;就像人耳听觉有频率限制,太高清的图片在手机上也是浪费资源,压缩后肉眼也看不出明显区别

Android利用DDMS性能调优

Android利用DDMS性能调优

前言:在android功能都开发完毕后,可以开始考虑优化代码。但要怎么入手呢?首先我们应该解决明显的UI卡顿,其次可以考虑内存优化等等。当然因为鄙人能力有限,有不到之处还请各位大神指教。

1.UI卡顿

UI卡顿的问题,我们可以利用ddms的traceview功能查看。




第一次点击后,会弹出一个对话框,直接点击确定,使用默认的即可.然后在界面上操作一下认为耗时的地方,在点击一下带红点的按钮.在IDE中就会出现traceview的视图.

我们在


这一栏中找到CPU_time/call,点击后排序.里面找我们自己的函数,就能看到较耗时的操作,在进行优化.

PS:如果已经点击红点按钮,界面操作无响应的话,多半是哪个地方ANR了,我们可以adb pull data/anr/*  d:/   拷贝出traces.txt文件 从而定位哪个函数在主线程进行了耗时操作.

2.堆内存泄漏

内存泄漏用IDE可点开红框


若是没有视图窗口,则在IDE上方窗口选windows -->show view 里面找到heap

我们在heap界面,然后每五秒选择gauge GC 若是heap size稳定在一个数值则表示没有内存泄漏的风险,若是heap size在不停的增大,则我们需要考虑创建对象的地方哪还值得优化.可以百度 Android内存优化.

>推荐使用LeakCancary,eclipse版本的jar包我这有,详情私信

3.线程耗时



我们在设备列表中选中我们的包名,然后打开红框的线程.在右侧就能看到当前应用所有的线程,utime表示我们的线程执行耗时,重点关注这个即可.

4.UI嵌套



点开这个按钮需要手机有root权限,若是没有的话,可在手机开发者选项中,打开GPU过度绘制,如果界面中红色的区域较多,则这部分区域是我们需要优化的

5.cpu占比

我们可在上述右侧部位找到system info的窗口,点击update后,即可看我们的应用瞬时占用的cpu比例.

todo : 如何分析各个函数占用cpu的比重

前言:之前写多媒体的时候,加载图片使用的Picasso框架,但图片列表很多依然有oom的问题,原来的图片分辨率(5024*4280)太大了,遂要压缩图片

对于一张5024*4280的图片(ARGB_8888 )来说,系统要分配多少内存呢?计算方法如下
5024*4280*4byte 约等 82.026M,吓人不
对于android设备来说,丢失一点像素点肉眼基本看不出来(肉眼八倍镜除外),所以如下是官方提供的demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}

public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

final int halfHeight = height / 2;
final int halfWidth = width / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}

return inSampleSize;
}

用法如下

1
2
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

网上有人说decodeStream会比decodeResource更节省内存,官方并无相关说明,需要用哪种方法解析Bitmap就用哪个方法吧,主要还是在于压缩图片

压缩原理就我的理解是先不分配图片的内存,待针对不同的设备(中密度,高密度,超高密度等)计算好压缩比例后再分配内存

ps:Picasso加载图片有一个fit()方法会根据imageview的大小自动压缩图片,就不需要上面的步骤了