1. 在模拟器中安装apk文件:
G:\work\android-sdk-windows\platform-tools里有个adb.exe工具
Adb install G:\work\Crack\xxx.apk
adb install -r <apk文件路径> :如果加-r参数会覆盖原来安装的软件并保留数据
批量安装:
for %%i in (*.apk) do adb install %%i
2. AndroidManifest.xml
<Manifest>属性
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.woody.test"
android:sharedUserId="string"
android:sharedUserLabel="string resource"
android:versionCode="integer"
android:versionName="string"
android:installLocation=["auto" | "internalOnly"| "preferExternal"] >
</manifest>
A、xmlns:android:这个是xml的命名空间,用于区分代表不同意义的同名元素(如table可以为表格,可以为桌子)
B、package:指定本应用内java主程序包的包名
c、versionCode:是给设备程序识别版本(升级)用的必须是一个interger值代表app更新过多少次,比如第一版一般为1,之后若要更新版本就设置为2,3等等。。。
d、versionName:这个名称是给用户看的,你可以将你的APP版本号设置为1.1版,后续更新版本设置为1.2、2.0版本等等。。。
e、installLocation:安装参数,是Android2.2中的一个新特性,installLocation有三个值可以选择:internalOnly、auto、preferExternal选择preferExternal,系统会优先考虑将APK安装到SD卡上(当然最终用户可以选择为内部ROM存储上,如果SD存储已满,也会安装到内部存储上)选择auto,系统将会根据存储空间自己去适应,选择internalOnly是指必须安装到内部才能运行,(注:需要进行后台类监控的APP最好安装在内部,而一些较大的游戏APP最好安装在SD卡上。现默认为安装在内部,如果把APP安装在SD卡上,首先得设置你的sdk api level为8以上(2.2),并且要配置android:installLocation这个参数的属性为preferExternal)
3. <Application>属性
一个AndroidManifest.xml中必须含有一个Application标签,这个标签声明了每一个应用程序的组件及其属性(如icon,label,permission等)
<application android:allowClearUserData=["true" | "false"]
android:allowTaskReparenting=["true" | "false"]
android:backupAgent="string"
android:debuggable=["true" | "false"]
android:description="stringresource"
android:enabled=["true" | "false"]
android:hasCode=["true" | "false"]
android:icon="drawableresource"
android:killAfterRestore=["true" | "false"]
android:label="stringresource"
android:manageSpaceActivity="string"
android:name="string"
android:permission="string"
android:persistent=["true" | "false"]
android:process="string"
android:restoreAnyVersion=["true" | "false"]
android:taskAffinity="string"
android:theme="resource ortheme">
</application>
a. android:icon:这个很简单,就是声明整个APP的图标,图片一般都放在drawable文件夹下
4. context:
首先什么是context?文档语焉不详,说是resource什么的,反正是没看懂,实际上可以认为它是一个指向parent对象的指针,受到那个parent对象的控制。
为什么需要context?试想一下这个语句:
Button myButton =newButton(this);
这个this就是context,前面说了它指向了parent对象,那指向了哪里?为什么需要这么做?原因是Button为了能完成自己的使命(响应各种操作)就得让Android系统知道自己是属于哪个Activity的,这个信息是必须的,因为只有这样Android系统才会对其进行管理,比如响应onClick()事件,否则系统连Button是属于哪个Activity的都不知道,怎么响应呢?
Application context和Activity context。
这是两种不同的context,也是最常见的两种。第一种中context的生命周期与Application的生命周期相关的,context随着Application的销毁而销毁,第二种中的context跟Activity的生命周期是相关的,但是对一个Application来说,Activity可以销毁几次,那么属于Activity的context就会销毁多次。至于用哪种context,得看应用场景,个人感觉用Activity的context好一点,不过也有的时候必须使用Application的context。
5. android.app.Application类是用来管理应用程序的全局状态的,比如载入资源文件。在应用程序启动的时候Application会首先创建,然后才会根据情况(Intent)来启动相应的Activity或者Service,应用程序的入口是application类的OnCreate方法。自定一个类继承自Application,然后再mainifest的Application标签里把name属性置为这个自定义类名,即可完成一个自定义application类
6. intent: activity是由Intent来启动的(在桌面上启动或在一个activity中启动另外一个activity(如在拨号程序中启动通讯录)),Intent就字面意思而言:“意图, 意向, 目的”, 基本上可以诠释这个对象的作用。它里面包含的就是一些信息,这些信息能够告诉我们当前发生了什么,以及想要干什么。Intent或者也可以说像一个需求说明一样,说明了当前的事件以及一些数据,接下来,Android会依据这个Intent的说明,为其找到一个Activity,并把这个Intent交给这个Activity。看起来Intent好像是征婚广告一样哦,Intent提出自己的一些描述,然后Android根据这些描述找到何时的 Activity。Intent有两种,一种是显式Intent,另一种是隐式Intent。显式Intent会在自己的说明中直接声明由谁(哪个Activity)来接收处理这个Intent。显式的Intent是说,我已经有了意中人了,告诉Android不用费劲找了,可以直接定位到意中人, 例如:
Intent intent = new Intent();
intent.putExtra("com.android.contacts.info", editText.getText().toString());
intent.setClass(ActivityLifecycle.this, AlertDialog.class);
putExtra用户设置intent附带的信息,前一个参数为信息名,必须带有一个包前缀,后一个参数为信息值,可以是int,byte,bool等类型,使用getStringExtra
,
getLongExtra
等传入信息名,获取信息值。
setClass用于设置响应intent的activity,第一个参数是context类型,第二个参数为响应的activity类的class成员(用于动态创建),类名也可以动态创建,所以使用setClassName(Context packageContext, String className)可以代替setClass,或使用setComponent(ComponentName component)代替,ComponentName对象含有packageContext和className信息
隐式Intent呢,比较含蓄,比较糊涂,比较模糊,还没有明确的目标,并且比较悲观,不会对对方提一些要求,只是描述了一下自己的情况,意思就是说,我就是我所描述的这样的一个人,谁能接受,谁就可以应征。:)
Intent intent = new Intent();
intent.putExtra("name", editText.getText().toString());
intent.setAction("com.roiding.sample.action.MAIN");
Intent只是设置了action,没有指定哪个class,意思是只要能响应这种action动作的activity都可以有机会启动
预置的action包括:
ACTION_CALL 活动 开始一个电话呼叫
ACTION_EDIT 活动 显示数据以给用户编辑
ACTION_MAIN 活动 开始任务的初始活动,没有输入数据也没有输出返回
ACTION_SYNC 活动 同步服务器与移动设备之间的数据
ACTION_BATTERY_LOW 广播接收器 电池低电量警告
ACTION_HEADSET_PLUG 广播接收器 耳机插拔
ACTION_SCREEN_ON 广播接收器 屏幕开启
ACTION_TIMEZONE_CHANGED 广播接收器 时区变化
等
也可以自定义action
7.intent包括3个部分:
a. action,有预置的action,也可以自己定义,自定义的action命名最好是包名.activity类名.action名
例如activity A(类名CA)中通过自定义action隐式启动activity B:
在CA中定义:
Public static final string MY_ACTION = “com.xxx.xxx.CA.READ”
接收intent的activity的mainifest中定义:
<activityandroid:name=". CB " android:label="@string/app_name">
<intent-filter>
<action android:name=" com.xxx.xxx.CA.READ" />
<categoryandroid:name="android.intent.category.DEFAULT " />
</intent-filter>
</activity>
CA中的启动代码:
Intent it = new Intent(MY_ACTION);
…..
StartActivity(it);
b. category(类别):标示是哪一类的intent,如LAUNCHER_CATEGORY表示该activity可以接收由桌面上的快捷方式启动(同时,在mainefest中设置它,app才能在桌面上生成快捷方式),category只能是预定义的一系列值
如果一个activity要接收隐式的intent,其必须在mainifest中配置:
<category android:name="android.intent.category.DEFAULT" />
含有如下配置的除外:
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
c. DATA(TYPE):data是intent中包含的数据,以一个URL表示,如一个联系人:
Content:// contacts/xxx
网址:
一般情况下,根据data可以自动判断出它的type(联系人,网址等),也可以指定TYPE,如果指定,则以指定的TYPE为准
以上三个部分都可以通过intent的构造函数或相关设置函数指定,不一定都要指定,但是如果指定了,无论是显式还是隐式启动,在activity的mainifest中必须配置一致的属性,才能接收相关的intent(category如果没有在intent中指定,会默认加一个category.DEFAULT),比如如果被启动的activity配置了同时data和action,则启动的intent必须同时setdata和setaction,但是如果被启动的activity同时配置了2个action,只要setaciton一次,set其中任意一个action就行了
接受隐式intent的activity至少配置一个action,不能只有data和category
8.Action.main决定哪个activity是启动时显示的activity,一般情况下,一个app只有一个activity配置此属性
10.Button,textview,checkbox等控件都是继承自view
11.控件布局的长或宽可以设为fill_parent(填满整个屏幕)或wrap_context(根据控件内容自动扩展大小以显示所有内容)
12. 通过addview可以在layout里用代码加入多个view,跟xml配置效果一样
13. MVC:activity相当于一个controler,它响应view的事件(实现一个xxlistener),调用mode的算法接口,一个activity可有多个view,view可由xml(layout\main.xml),也可在代码里写
Mode即自己实现的数据操作的算法,mode可以加入一个或多个view作为观察者,数据更新时,通知view更新
View即界面显示,view关联mode和controler实例,mode实例用于处理数据,controler用做view事件的响应
14.Xml命名空间:
<xmlns:空间名 = “url”>,url一般是一个网站地址,并不代表要连接这个网站去获取,只是用来唯一标识一个命名空间(网址是唯一的),也可以不用网址,随便用一个串即可
带空间名的命名空间必须加到元素的标签前才表明使用这个命名空间,不带空间名得命名空间默认加到它和它的所有子元素(除非其子元素又显式加了其他命名空间名)。
可以在同一文档的任意位置声明ns,一个文档可以声明多个ns
<books xmlns=”www.zhouyi.com”>
<book name=”A”/>
<book xmlns:other=www.other.com name=”B”/>
<book xmlns=”ww.other2.com”name=”C”>
</books>
Books和第1,2个book在一个ns里,第3个book在另一个ns里
15.Activity和application都是context的子类CreatPackageContext是context的静态方法,它传入主activity的package名即可得到对应application的context,以此调用此application中继承自context的所有方法(如获取资源等)
16.Back键是关闭(音乐播放等特例除外),home是切换,back后activity调用ondestory,再启动调用oncreate,home后调用onstop,再启动调用onpause
17.线性布局默认为横向
18.$,/等字符在android中都是特殊转义字符,必须用类似”\\$”表示原字符,注意是两个斜杠
19.空串不是null,是””
20.Android默认编码是utf-8,也就是说eclipse中的android插件代码编辑器中的默认编码设置为utf-8(英文字母编码上,utf-8和ascii是一样的),这样代表两个含义:a.在编辑器上写的字串是utf-8编码的(即代码和注释都是utf-8编码)。b.从文本中读取字串会默认其为utf-8编码(按utf-8的编码规则去解析字串,如果文本以其他字符集保存,就会出现乱码,因为是以utf-8的编码规则去解析了非utf-8字串),
可以在eclipse中设置默认编码为其他编码(java插件为unicode编码),比如unicode编码的文件,默认下会读成乱码,把默认编码设成unicode就不会了(可以针对单个文件,工程,文件夹设置),但是由于android系统只支持utf-8,unicode编码的字串在textview等控件上显示时会是乱码(因为控件是按照utf-8的编码规则去解析字串的)
22. 坐标原点在左上角,X轴向右为正,y轴向下为正
23. 中文windows系统默认编码为GB2312(GBK),GBK是2312的扩展,兼容2312
24.事件响应可以先扩展view的子类,在子类中覆写OnXXX方法,也可以在事件监听器(xxxListener)中实现Onxxx接口
25.Layout放在activity中,控件必须放在layout中,activity和view一样可以响应onkeydown/up,ontouchevent等各种按键和触控事件
26.继承自viewgroup的控件可以包含子控件,如listview等,直接继承自view的则不可,如button
27. Bundle相当于一个map,由key,value对组成,放入intent中,用户传递数据给activity
Intent intent =new Intent(A.this, B.class);
/* 通过Bundle对象存储需要传递的数据*/
Bundle bundle = new Bundle();
/*字符、字符串、布尔、字节数组、浮点数等等,都可以传*/
bundle.putString("Name","feng88724");
bundle.putBoolean("Ismale",true);
/*把bundle对象assign给Intent*/
intent.putExtras(bundle);
startActivity(intent);
接受
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*加载页面*/
setContentView(R.layout.main);
/*获取Intent中的Bundle对象*/
Bundle bundle =this.getIntent().getExtras();
/*获取Bundle中的数据,注意类型和key*/
String name =bundle.getString("Name");
boolean ismale =bundle.getBoolean("Ismale");
}
28. 启动时强制横屏显示:
AndroidManifest.xml中配置activity属性:
android:screenOrientation="landscape"
29.各种layout都是继承自viewgroup,viewgroup继承自view
30.SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX 可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
31.IMEI是手机的身份识别码.俗称串码.和手机号码没有关系.IMSI是网络接入识别码,是一个手机号码的唯一身份证明
32.布局
1. 布局(layout):在layout/main.xml中配置,view必须包含在layout中,layout有五种(可嵌套使用)
A. Framelayout:各个view在左上角重叠
B. Linearlayout:可分为水平和垂直两种布局,按比重横排、竖排或组合排列,可以只设其中几个view的比重,此时这几个view按设置的比重占据剩余空白的全部
C. Absolutelayout:使用坐标随意指定元素的位置,不推荐使用,不同设备显示可能有问题
D. Relativelayout:可以定义元素相对父元素或其他元素的位置
E. Tablelayout:把屏幕分成单元格,里面存放view
2. Linearlayout布局的weight只在布局和控件的android:layout_width属性为"fill_parent"时起作用。
3. RelativeLayout默认值是Gravity.LEFT| Gravity.TOP,说明RelativeLayout的元素如果不设置位置,会从左上角开始堆叠
4. LinearLayout中多个控件竖排,android:layout_height设置为wrap_content并不能保证多个控件都显示出来,如果中间有比较长的控件,占满了剩余的空间,则这个控件下面的控件可能在屏幕外了,横排类似
33.smali汉化,
xml中的英文直接汉化保存即可
如果是修改smali文件,在保存时我们应该选择“另存为”,在弹出的对话框的“格式”中,选择“UTF-8-无BOM“这一项,直接覆盖保存即可。(特殊情况下,这样也不行,原因不详)
在开发中为控件添加Listener是非常常见的工作,最简单的添加Listener方式可以这样:
- findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- // Do stuff
- }
- });
采用上述方法添加Listener有个缺点就是如果控件太多的话,Listener数量也会增多,因此,可以采用如下的小窍门减少Listener的数量:
- View.OnClickListener handler = View.OnClickListener() {
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.Button01: // doStuff
- break;
- case R.id.Button02: // doStuff
- break;
- }
- }
- }
- findViewById(R.id.myButton).setOnClickListener(handler);
- findViewById(R.id.myOtherButton).setOnClickListener(handler);
在Android1.6里面,添加Listener的工作变得相当的简单(感觉更像在做网页编程!),具体步骤如下:
1.首先在layout里面定义Button并指定响应的Listener
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:text="Button01"
- android:id="@+id/Button01"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="myClickHandler01"
- />
- <Button
- android:text="Button02"
- android:id="@+id/Button02"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="myClickHandler02"
- />
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- </LinearLayout>
其中以下这两行就是新增的特性:
android:onClick="myClickHandler01"
android:onClick="myClickHandler02"
2.在活动里面定义public的方法myClickHandler01、和myClickHandler02(注意这两个方法必须有一个View的形参)。
- package com.ray.test;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- public class TestOnClickListener extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- public void myClickHandler01(View target){
- setTitle("myClickHandler01");
- }
- public void myClickHandler02(View target){
- setTitle("myClickHandler02");
- }
- }
当然,你也可以采用这种写法:
将两个按钮设置到同一个Listener
android:onClick="myClickHandler"
android:onClick="myClickHandler"
- package com.ray.test;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- public class TestOnClickListener extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- public void myClickHandler(View target){
- switch (target.getId()) {
- case R.id.Button01:
- setTitle("myClickHandler01");
- break;
- case R.id.Button02:
- setTitle("myClickHandler02");
- break;
- }
- }
- }
如果一个layout可能需要被多次复用,比如多view或者多activity的应用中,需要保持打头的标题栏在各个view或activity中保持不变,这时候可以把这个标题栏在各个布局文件里重复写一遍,但是最好的方法是使用include复用,以减少重复的布局内容,以下是一个例子:
layout_buttom.xml中存放一个应用位于底部的功能区,这个功能区在切换activity或view时是不变的:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<Button android:id="@+id/btqq"
android:layout_width="wrap_content"
android:text="功能1"
android:layout_height="40dip">
</Button>
<Button android:id="@+id/btjq"
android:layout_width="wrap_content"
android:text="功能2"
android:layout_height="40dip">
</Button>
</LinearLayout>
layout_main.xml是主界面,也是底部放置了功能区的界面之一:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:weightSum="1" android:orientation="vertical">
<LinearLayout android:id="@+id/AdLinearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"/>
<FrameLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1">
........
</FrameLayout>
<include layout="@layout/layout_buttom"/>
</LinearLayout>
activity和application里都可以设置android:label标签,activity的优先级高于application,也就是说两者都设置这个标签的话,activity的值覆盖application
application里设置了此标签,其他activity没有设置的情况下,应用程序名在桌面上的名字和所有activity的title是这个设置的标签
application里设置了此标签,主activity中也设置了此标签,则应用程序名和主activity的title都是主activity中设置的标签,其他非主activity的title如果没有自己设置此标签,还是使用application中设置的标签,如果其他非主activity也设置了此标签,则其title就是自己设置的这个标签
37.Rss解析:
a. 使用HttpURLConnection连接目标RSS的URL
URL url = new URL(strRssURL);
HttpURLConnection localHttpURLConnection = (HttpURLConnection) url.openConnection();
localHttpURLConnection.connect();
b. 得到RSS的输入流(RSS的描述XML):
InputStream localInputStream = localHttpURLConnection.getInputStream();
c. 使用SAXParser解析RSS,解析的过程中不断把解析到的数据填充到存储RSS内容的数
据结构中
d. 如果rss需要通过list展现,把rss中的内容通过adapter显示到list控件中