欢迎前往我的个人博客查看原文:Tristan Blog
认知: ART是趋势,DalVik已经慢慢在被淘汰
ART,即Android Runtime。ART 的机制与 Dalvik 不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器(just in time ,JIT)转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样的话,应用的启动(首次)和执行都会变得更加快速。
参考: Android 中的Dalvik和ART是什么,有啥区别?
bt.setOnClickListener(new onClickListener())
android:onClick = "something"
,然后在activity中定义一个同名的方法public void something(View v){}
这个方法所接收的参数为一个View对象,当按钮被按下时,系统会调用这个something()
方法注意,在onClick方法中传入的View对象是被点击的button对象,所以多个button可以共用一个点击监听,只要在监听里面用
bt.getId()
来最终区分出来是哪个button就可以分别处理而不干扰。
有一个疑问就是:共用监听or单独监听(每个button一个内部类)or在layout中设置onClick
这几种方式在消耗内存上有啥区别?
在xml文件中:
在java代码中:
btn.getBackground().setAlpha(100)
//0~255透明度数值量:
“aabbggrr”
,其中“aa=alpha”(00 到 ff);“bb=blue”(00 到 ff);“gg=green”(00 到 ff);“rr=red”(00 到 ff)。开发中用的最多的是linearlayout
和relativelayout
单纯线性布局永远不会发生组件的重叠
LinearLayout中的layout_weight属性:
layout_weight
属性用于分配LinearLayout
中的的额外空间(extra space)。
如果View不想拉伸的话,layout_weight
值设置为0。否则的话这些像素会按比例分配到weight值大于0的所有View。
换句话说,也就是android:layout_weight
属性告知LinearLayout
如何进行子组件的布置安排。
参考:
LinearLayout的layout_weight属性
在relativelayout
中默认的对齐方式是左对齐和顶部对齐,可以通过设置android:layout_align*="true"("id")
或者layout_above="id"
或者layout_toLeftOf="@id/*"
等属性来改变,而居中等可以通过android:centerIn*
来设置
假设有两个对象(id分别为tv1和tv2)第二个对象设置了两个属性alignRight="@id/tv1"
、alignLeft="@id/tv1"
,那么第二个对象就会和第一个对象等宽
帧布局是五大布局中最简单的布局方式,在需要布局中有空间重叠的情况下才使用。
frameLayout
中的所有视图都已以层叠的方式展现的。第一个添加到布局中的视图显示在最底层,最后一个被放在最顶层。上一层的视图会覆盖下一层的视图,因此该布局类似于堆栈布局。
在framelayout
中子视图默认的对齐方式也是左对齐和顶部对齐,可以通过设置android:layout_gravity="left|buttom"
等属性来改变
在framelayout
中,空间的layout_margin
属性需要依赖layout_gravity
属性,否则设置无效。layout_margin
所示的边缘值是相对于控件的layout_gravity
所定义的参考点而言的。
如果以图片作为linearLayout
的背景,那么将无法控制布局的高和宽,其尺寸会不受控制地适应图片的大小,因此采用frameLayout
配合imageView
添加可大小可控的背景
<TableLayout>
<TableRow> TableRow>
<TavleRow> TableRow>
TableLayout>
宽高:
在表格布局中每个tableRow
的宽高是有个默认值的,默认的宽是match_parent
默认的高是wrap_content
,同时宽高也是不可更改的,改了也无效
可以在TableLayout
中设置stretchColumns="*"
设置拉伸列
分割线:
如果想在表格中插入一个分割线,可以在
中加入一个直接子标签
,将其高度设为1个dp,设置下颜色就好了
两个独有的属性:
可以通过layout_column=""
直接设置某个元素在第几列,这样就可以不必从第0列开始
可以通过layout_span=""
来设置某一个元素占几列
存储空间包括内部存储空间和外部存储空间
内部存储读写文件不需要权限,因为只能写自己包内的文件,其他包不能动,除非有root权限
File file = new File("data/data/com.example.*/file");
FileOutputStream fos = new FileOutStream(file);
fos.write(string.getBytes());
可以通过getFilesDir()
来获得data/data/com.example.*/file
文件夹的路径.,所以可以这样写:
File file = new File(getFilesDir(),“name.txt”);
而通过getCacheDir()
可以获得
data/data/com.example.*/cache
文件夹的路径
从源码看,两者的区别是:当rom空间不够的时候,cache文件夹中的东西有可能会被系统删除,但是不能指望系统去删除,应该自己设置一个阈值
在设置中点击存储,选择相应的应用,可以选择清除缓存和清除数据,前者会清空cache文件夹中的所有文件,而后者会删除包内所有的用户文件
外部存储写数据需要权限WRITE_EXTERNAL_STORAGE
,而读数据则不一定,要看开发者选项里面是否勾选了sd卡读写保护
各个厂商的sd卡的路径差不多都不一样,要注意
File file = new File("sdcard/file.*")
这个api名字突出一个长啊,使用之前先判断sd卡是否可用
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = new File(Environment.getExternalStorageDirectory(),"name");
}
其中,sd卡的状态可以有:
状态 | 说明 |
---|---|
REMOVE |
没有插sd卡 |
UNMOUNT |
sd卡已插,但是没有挂载 |
CHECKING |
sd卡正在被系统遍历 |
MOUNTED |
sd卡准备就绪,可以读写 |
MOUNTED_READ_ONLY |
sd卡可用,但是只读 |
可以参看设置系统应用的源码,放在package/apps/Settings
中,具体用的时候可以google找轮子
sd卡存储空间 = 可用的区块数量*区块大小(blockSize)
权限的表现形式:
d rwx rwx rwx
一共十位
d
:代表文件夹,文件是-rwx
:决定owner用户对此文件的权限
具体编程时,当我们需要在应用中写入一个一定权限的文件的时候:
public void bt_click(View v){
//此api会把文件写到data/data/com.xxx.xxx/files文件夹下
try{
FileOutputStream fos = openFileOutput("example.txt", MODE_WORLD_READABLE);
fos.write("哈哈".getBytes());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
其中要说明的是openFileOutput是Context提供的一个很要用的方法,但是只能写到本应用对应的文件夹下:
SharedPreferences的使用非常简单,能够轻松的存放数据和读取数据。SharedPreferences只能保存简单类型的数据,例如,String、int等。一般会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中,再用SharedPreferences保存。
具体的方法参看博文:
Android SharedPreferences使用以及原理详解
**注意:**要使用Activity类的getSharedPreferences方法获得SharedPreferences对象,而不要new一个新的对象,否则效率不高
真机调试时eclipse的file explorer打不开data文件夹:
当用真机开发Android时,连接了Eclipse后,默认在File Explorer下是达不开我们手机的data文件夹的,这里打不开是因为权限不足。以下有个小技巧可以解决这问题。
首先,测试机先root,然后在手机上安装上Root Explorer 管理器(或类似软件),再将/data/data及其子文件夹下的访问权限都修改为可读可写可执行即可。这时候再使用eclipse的File Explorer就可以展开了,这时候就可以查看应用下的SQLite数据库了。
当devices中的设备显示不出来的时候:
直接使用需要在cmd中cd到sdk的目录下使用adb start-server
指令,也可以将该目录直接加入到系统变量的path中,这样直接就在cmd任意位置输入指令即可。本质是个socket。
相关的指令:
adb start-server
其实任何一条adb指令都可以重启adbadb kill-server
杀死进程adb install apk的路径
安装apkadb uninstall com.tristan.something
这里是写的包名adb devices
显示所有连接的android设备adb shell
进入android系统的命令行(linux)当你的手机助手占用的系统的adb的端口(5037)怎么办?
首先通过adb devices
查看端口,然后在windows下cmd使用netstat -ano
查看当前系统各个端口被什么进程所占用
项目组织文件:
manifeast中的package是android分辨应用的唯一标识,和gen目录下的包名相同,与src目录下的不同
当应用涉及到用户权限时,需要到manifesat中去添加权限(可以通过可视化操作)
root工具:
实验室手机Nexus5快速root工具
查看日志:
在logcat中设置过滤器的时候最好根据Tag
来过滤(比如System.out
输出的日志的tag就是System.out
,级别为Info
),而不要用Application
来过滤
logcat语句:
Log.e(tag,string)
Log.i(tag,string)
…
URI和URL的区别
//举例,拨号逻辑
public void onclick(View v){
EditText et = (EditText) findViewById(R.id.et);
String phone = et.getText().toString();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phone));
}