版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/simplebam/article/details/60324135
PS:本笔记配对传智播客的安卓基础视频-20151228-Android基础视频
对应视频的课件解答:张萍老师:http://bbs.itcast.cn/?197082
数据存储与界面展示
Android工程的目录详解:
Android版本介绍、常用手机的分辨率:
Android测试程序需要添加的代码:
1.在清单文件中的application里面添加下面的代码配置函数库
<span style="color:#000000"><code><span style="color:#006666"><<span style="color:#4f4f4f">uses-library</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.test.runner"</span>/></span></code></span>
- 1
2.再在清单文件application外面添加下面的三行代码:
<span style="color:#000000"><code><instrumentation
android:name=<span style="color:#009900">"android.test.InstrumentationTestRunner"</span>
android:targetPackage=<span style="color:#009900">"com.example.simpledail"</span> android:label=<span style="color:#009900">"TestApplication"</span> /></code></span>
- 1
- 2
- 3
PS:记得修改targetPackage为当前你需要测试程序的包的路径
SharedPreferences的介绍:
背景:对于软件配置参数的保存,如果是window软件,通常会采用ini文件进行保存;如果是 j2se应用,通常会采用properties属性文件进行保存;如果是Android应用,Android 平台提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data//shared_prefs目录下。
因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式分别是:
Context.MODE_PRIVATE:
为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:
模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE
用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;
MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
如果希望文件被其他应用读和写,可以传入:
openFileOutput(“123.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
详情看
Android中使用SharedPreferences进行数据存储及文件操作-txgc_wm-ChinaUnix博客
1.存数据,生成的是xml文件
<span style="color:#000000"><code> <span style="color:#880000">//1 获取sp的实例</span>
SharedPreferences sp = getSharedPreferences(<span style="color:#009900">"config"</span>, Context.MODE_PRIVATE);<span style="color:#880000">//confid为存储文件的姓名</span>
<span style="color:#880000">//2 获取编辑器</span>
SharedPreferences.Editor <span style="color:#000088">edit</span> = sp.<span style="color:#000088">edit</span>();
<span style="color:#880000">//3.存数据,第一个为key,第二个为值</span>
<span style="color:#000088">edit</span>.putString(<span style="color:#009900">"username"</span>,<span style="color:#009900">"yueyue"</span>);
<span style="color:#000088">edit</span>.putString(<span style="color:#009900">"password"</span>,<span style="color:#009900">"123456"</span>);
<span style="color:#880000">//4.提交数据</span>
<span style="color:#000088">edit</span>.commit();</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.拿数据:
<span style="color:#000000"><code> <span style="color:#880000">//1 获取sp的实例</span>
SharedPreferences sp = getSharedPreferences(<span style="color:#009900">"config"</span>, Context.MODE_PRIVATE);<span style="color:#880000">//confid为存储文件的姓名</span>
<span style="color:#880000">//2 取数据 第一个为值的key,第二个为默认返回值(当没有取到值的时候)</span>
<span style="color:#4f4f4f">String</span> username = sp.getString(<span style="color:#009900">"username"</span>, <span style="color:#009900">""</span>);</code></span>
- 1
- 2
- 3
- 4
- 5
官方google给出的实例:
http://www.android-doc.com/guide/topics/data/data-storage.html#pref
数据库SQLite学习笔记:
1.sqlite3 打开数据库
2.chmod lunix下修改文件的权限
3.改变dos的编码方式 chcp936(GBK) chcp65001(utf-8)
如何创建一个数据库
定义一个类继承SqliteOpenHelper
<span style="color:#000000"><code> <span style="color:#880000">/**
*
*<span style="color:#4f4f4f"> @param</span> context 上下文环境
*<span style="color:#4f4f4f"> @param</span> name 数据库名字
*<span style="color:#4f4f4f"> @param</span> factory 游标工厂,一般用不上
*<span style="color:#4f4f4f"> @param</span> version 数据库版本号
*/</span>
<span style="color:#000088">public</span> <span style="color:#009900">MySqliteHelper</span>(Context context, String name, SQLiteDatabase.CursorFactory factory, <span style="color:#000088">int</span> version) {
<span style="color:#000088">super</span>(context, name, factory, version);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果感觉参数太多或者有些参数不需要,可以写成下面这种
<span style="color:#000000"><code> <span style="color:#880000">/**
*
*<span style="color:#4f4f4f"> @param</span> context 上下文环境
*/</span>
<span style="color:#000088">public</span> <span style="color:#009900">MySqliteHelper</span>(Context context) {
<span style="color:#000088">super</span>(context, <span style="color:#009900">"mysqlite.db"</span>, <span style="color:#000088">null</span>, <span style="color:#006666">1</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
SQLite增删改查:
打开或者创建数据库
库增加:一般使用系统的继承方法那里增加数据库名字
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#009900">MySQLiteHelper</span>(Context context) {
<span style="color:#000088">super</span>(context, <span style="color:#009900">"sqlitehaha.db"</span>, <span style="color:#000088">null</span> , <span style="color:#006666">1</span>);
<span style="color:#880000">// TODO Auto-generated constructor stub</span>
}</code></span>
- 1
- 2
- 3
- 4
Minactivity.java中:
<span style="color:#000000"><code>MySQLiteHelper helper = <span style="color:#000088">new</span> MySQLiteHelper(<span style="color:#000088">this</span>);
<span style="color:#880000">// MySQLiteHelper helper = new MySQLiteHelper(getApplicationContext());</span>
<span style="color:#880000">// 打开或者创建数据库 如果是第一次就是创建</span>
SQLiteDatabase sqLiteDatabase = helper.getWritableDatabase();
<span style="color:#880000">// 打开或者创建数据库 如果是第一次就是创建 如果磁盘满了 返回只读的</span>
SQLiteDatabase readableDatabase1 = helper.getReadableDatabase();</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
表格操作
表增加
<span style="color:#000000"><code>
db.execSQL("<span style="color:#000088">create</span> <span style="color:#000088">table</span> info(_id <span style="color:#000088">integer</span> <span style="color:#000088">primary</span> <span style="color:#000088">key</span> autoincrement,name <span style="color:#000088">varchar</span>(<span style="color:#006666">20</span>),phone <span style="color:#000088">varchar</span>(<span style="color:#006666">20</span>))<span style="color:#009900">");</span></code></span>
- 1
- 2
表修改
<span style="color:#000000"><code>db.execSQL("<span style="color:#000088">alter</span> <span style="color:#000088">table</span> info <span style="color:#000088">add</span> money <span style="color:#000088">varchar</span>(<span style="color:#006666">20</span>)<span style="color:#009900">");</span></code></span>
- 1
数据操作
数据增加:
1.
<span style="color:#000000"><code><span style="color:#880000">//执行增加一条的sql语句 </span>
db.execSQL(<span style="color:#009900">"insert into info(name,phone) values(?,?)"</span>, <span style="color:#000088">new</span> <span style="color:#4f4f4f">Object</span>[]{<span style="color:#009900">"张三"</span>,<span style="color:#009900">"1388888"</span>});</code></span>
- 1
- 2
2.
<span style="color:#000000"><code> <span style="color:#880000">/**
* table 表名 ContentValues 内部封装了一个map key: 对应列的名字 value对应的值
**/</span>
ContentValues values = <span style="color:#000088">new</span> ContentValues();
values.put(<span style="color:#009900">"name"</span>, <span style="color:#009900">"王五"</span>);
values.put(<span style="color:#009900">"phone"</span>, <span style="color:#009900">"110"</span>);
<span style="color:#880000">// 返回值代表插入新行的id</span>
<span style="color:#000088">long</span> insert = db.insert(<span style="color:#009900">"info"</span>, <span style="color:#000088">null</span>, values); <span style="color:#880000">// 底层就在组拼sql语句</span>
<span style="color:#880000">// [3]数据库用完需要关闭</span>
db.close();
<span style="color:#000088">if</span> (insert > <span style="color:#006666">0</span>) {
Toast.makeText(getApplicationContext(), <span style="color:#009900">"添加成功"</span>, <span style="color:#006666">1</span>).show();
} <span style="color:#000088">else</span> {
Toast.makeText(getApplicationContext(), <span style="color:#009900">"添加fail"</span>, <span style="color:#006666">1</span>).show();
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
数据修改
1.
<span style="color:#000000"><code>db.execSQL(<span style="color:#009900">"update info set phone=? where name=? "</span>, <span style="color:#000088">new</span> <span style="color:#4f4f4f">Object</span>[]{<span style="color:#009900">"138888888"</span>,<span style="color:#009900">"张三"</span>});</code></span>
- 1
2.
<span style="color:#000000"><code>ContentValues values = new ContentValues();
values.put("phone", "114");
//代表更新了多少行
int <span style="color:#000088">update</span> = db.<span style="color:#000088">update</span>(<span style="color:#009900">"info"</span>, <span style="color:#000088">values</span>, <span style="color:#009900">"name=?"</span>, new String[]{<span style="color:#009900">"王五"</span>});
//int <span style="color:#000088">update</span> = db.<span style="color:#000088">update</span>(<span style="color:#009900">"info"</span>, <span style="color:#000088">values</span>, <span style="color:#009900">"name='王五',null"</span>);
db.close();
Toast.makeText(getApplicationContext(), "更新了"+<span style="color:#000088">update</span>+<span style="color:#009900">"行"</span>, <span style="color:#006666">0</span>).<span style="color:#000088">show</span>();</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
数据删除
1.
<span style="color:#000000"><code>db.execSQL(<span style="color:#009900">"delete from info where name=?"</span>, <span style="color:#000088">new</span> <span style="color:#4f4f4f">Object</span>[]{<span style="color:#009900">"张三"</span>});</code></span>
- 1
2.
<span style="color:#000000"><code>//返回值代表影响的行数
int <span style="color:#000088">delete</span> = db.<span style="color:#000088">delete</span>(<span style="color:#009900">"info"</span>, <span style="color:#009900">"name=?"</span>, new String[]{<span style="color:#009900">"王五"</span>});
//int <span style="color:#000088">delete</span> = db.<span style="color:#000088">delete</span>(<span style="color:#009900">"info"</span>, <span style="color:#009900">"name='王五'"</span>, <span style="color:#000088">null</span>);
db.close();
Toast.makeText(getApplicationContext(), "删除了"+<span style="color:#000088">delete</span>+<span style="color:#009900">"行"</span>, <span style="color:#006666">0</span>).<span style="color:#000088">show</span>();</code></span>
- 1
- 2
- 3
- 4
- 5
数据查询
1.
<span style="color:#000000"><code>Cursor cursor = db.rawQuery(<span style="color:#009900">"select * from info"</span>, <span style="color:#006666">null</span>);
<span style="color:#000088">if</span> (cursor!= <span style="color:#006666">null</span> && cursor.getCount()><span style="color:#006666">0</span>) {
<span style="color:#000088">while</span>(cursor.moveToNext()){
<span style="color:#880000">//columnIndex代表列的索引 </span>
<span style="color:#4f4f4f">String</span> name = cursor.getString(<span style="color:#006666">1</span>);
<span style="color:#4f4f4f">String</span> phone = cursor.getString(<span style="color:#006666">2</span>);
System.out.println(<span style="color:#009900">"name:"</span>+name+<span style="color:#009900">"========="</span>+phone);
}
} </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2.
<span style="color:#000000"><code>Cursor cursor = db.query(<span style="color:#009900">"info"</span>, <span style="color:#000088">new</span> <span style="color:#4f4f4f">String</span>[]{<span style="color:#009900">"name"</span>,<span style="color:#009900">"phone"</span>}, <span style="color:#009900">"name=?"</span>, <span style="color:#000088">new</span> <span style="color:#4f4f4f">String</span>[]{<span style="color:#009900">"王五"</span>}, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>);
<span style="color:#000088">if</span> (cursor!= <span style="color:#006666">null</span>&&cursor.getCount()><span style="color:#006666">0</span>) {
<span style="color:#000088">while</span>(cursor.moveToNext()){
<span style="color:#880000">//columnIndex代表列的索引 </span>
<span style="color:#4f4f4f">String</span> name = cursor.getString(<span style="color:#006666">1</span>);
<span style="color:#4f4f4f">String</span> phone = cursor.getString(<span style="color:#006666">2</span>);
System.out.println(<span style="color:#009900">"name:"</span>+name+<span style="color:#009900">"========="</span>+phone); </code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
事物
<span style="color:#000000"><code> db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
PS:Cursor运用
代码模板:
<span style="color:#000000"><code>MyOpenHelper myOpenHelper = <span style="color:#000088">new</span> MyOpenHelper(getApplicationContext());
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
Cursor cursor = db.query(<span style="color:#009900">"info"</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>);<span style="color:#880000">// 得到info数据表的数据</span>
<span style="color:#000088">if</span>(cursor!=<span style="color:#006666">null</span> && cursor.getCount()><span style="color:#006666">0</span>)
{<span style="color:#880000">// 判断cursor不为空以及数据库的数据行>0</span>
<span style="color:#000088">while</span> (cursor.moveToNext()) {<span style="color:#880000">// 将cursor向下解析</span>
<span style="color:#4f4f4f">String</span> name = cursor.getString(<span style="color:#006666">1</span>);<span style="color:#880000">// 得到数据表格中的名字列数据</span>
<span style="color:#4f4f4f">String</span> phone = cursor.getString(<span style="color:#006666">2</span>);<span style="color:#880000">// 得到数据表格中的名字工资列数据</span>
System.out.println(<span style="color:#009900">"name"</span> + name + <span style="color:#009900">"----"</span> + phone);
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Intent简单学习:
<span style="color:#000000"><code> <span style="color:#880000">// 点击按钮 实现拨打电话的功能</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click1</span>(View v) {
<span style="color:#880000">// [1]创建意图对象</span>
Intent intent = <span style="color:#000088">new</span> Intent();
<span style="color:#880000">// [2] 设置拨打的动作</span>
intent.setAction(Intent.ACTION_CALL);
<span style="color:#880000">// [3]设置拨打的数据</span>
intent.setData(Uri.parse(<span style="color:#009900">"tel:"</span> + <span style="color:#006666">119</span>));
<span style="color:#880000">// [4]开启Activity 记得加上权限</span>
startActivity(intent);
}
<span style="color:#880000">// 点击按钮 跳转到TestActivity</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click2</span>(View v) {
<span style="color:#880000">// [1]创建意图对象 意图就是我要完成一件事</span>
Intent intent = <span style="color:#000088">new</span> Intent();
<span style="color:#880000">// [2] 设置跳转的动作</span>
intent.setAction(<span style="color:#009900">"com.itheima.testactivity"</span>);
<span style="color:#880000">// [3] 设置category</span>
intent.addCategory(<span style="color:#009900">"android.intent.category.DEFAULT"</span>);
<span style="color:#880000">// [4]设置数据</span>
<span style="color:#880000">// intent.setData(Uri.parse("itheima:"+110));</span>
<span style="color:#880000">// [5]设置数据类型</span>
<span style="color:#880000">// intent.setType("aa/bb");</span>
<span style="color:#880000">// [6]注意 小细节☆ 如果setdata 方法和 settype 方法一起使用的时候 应该使用下面这个方法</span>
intent.setDataAndType(Uri.parse(<span style="color:#009900">"itheima1:"</span> + <span style="color:#006666">110</span>), <span style="color:#009900">"aa/bb1"</span>);
<span style="color:#880000">// [4]开启Activity</span>
startActivity(intent);
}</code></span>
- 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
Listview :
PS:不管是什么adapter,作用就是把数据展示到listview
Listview出现内存溢出的解决办法:
<span style="color:#000000"><code><span style="color:#006666">10</span>-<span style="color:#006666">28</span> <span style="color:#006666">03</span>:<span style="color:#006666">16</span>:<span style="color:#006666">57.267</span>: E/dalvikvm-heap(<span style="color:#006666">1618</span>): <span style="color:#000088">Out</span> <span style="color:#000088">of</span> memory <span style="color:#000088">on</span> a <span style="color:#006666">24332</span>-byte allocation. <span style="color:#880000">// 内存溢出问题</span></code></span>
- 1
convertView简介:
The old view to reuse, if possible.Note: You should check that this view is non-null and of an appropriate type before using
Listview的行高设置建议:
android:layout_width=”match_parent”
android:layout_height=”match_parent”
listView优化
<span style="color:#000000"><code> 1:复用convertView
2:复用ViewHolder让其减少findViewById()次数
3:static ViewHolder
4:分页算法
</code></span>
- 1
- 2
- 3
- 4
参考代码:
<span style="color:#000000"><code> ViewHolder viewHolder = null<span style="color:#880000">;</span>
if(convertView == null){
viewHolder = new ViewHolder()<span style="color:#880000">;</span>
convertView = View<span style="color:#009900">.inflate</span>()<span style="color:#880000">;</span>
viewHolder<span style="color:#009900">.text</span>1 = convertView<span style="color:#009900">.findViewById</span>(R<span style="color:#009900">.id</span><span style="color:#009900">.text</span>1)<span style="color:#880000">;</span>
convertView<span style="color:#009900">.setTag</span>(viewHolder)<span style="color:#880000">;</span>
}else{
viewHolder = (ViewHolder)convertView<span style="color:#009900">.getTag</span>()<span style="color:#880000">;</span>
}
viewHolder<span style="color:#009900">.text</span>1<span style="color:#009900">.setText</span>(<span style="color:#009900">"文本内容"</span>)<span style="color:#880000">;</span>
static class ViewHolder{
TextView text1<span style="color:#880000">;</span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
特点:
1.线性布局、相对布局都继承ViewGroup,ViewGroup可以有自己的孩子
2.通过一个打气筒inflate可以把一个布局文件转换成一个View对象
生成打气筒的常用三种方式:
<span style="color:#000000"><code> <span style="color:#880000">// [1]想办法把我们自己定义的布局转换成一个view对象 就可以了</span>
View view;
<span style="color:#000088">if</span> (convertView == <span style="color:#000088">null</span>) {
<span style="color:#880000">// 创建新的view对象 可以通过打气筒把一个布局资源转换成一个view对象</span>
<span style="color:#880000">// resource 就是 我们定义的布局文件</span>
<span style="color:#880000">// [一☆☆☆☆]获取打气筒服务</span>
<span style="color:#880000">// view = View.inflate(getApplicationContext(), R.layout.item,</span>
<span style="color:#880000">// null);</span>
<span style="color:#880000">// [二☆☆☆☆]获取打气筒服务</span>
<span style="color:#880000">// view=LayoutInflater.from(getApplicationContext()).inflate(R.layout.item,</span>
<span style="color:#880000">// null);</span>
<span style="color:#880000">// [三☆☆☆☆]获取打气筒服务</span>
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, <span style="color:#000088">null</span>);
} <span style="color:#000088">else</span> {
<span style="color:#880000">// 复用历史缓存对象</span>
view = convertView;
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
网络编程
主线程一般作为UI线程,更新UI(如view等),子线程不可以直接更新U,需要更新的话可以调动Handler
PS:联网操作的时候记得加上联网权限:
<span style="color:#000000"><code> <span style="color:#006666"><<span style="color:#4f4f4f">uses-permission</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.permission.INTERNET"</span>/></span></code></span>
- 1
1.HttpURLConnection:用于接受和发送数据
<span style="color:#000000"><code>HttpURLConnection urlConnection =<span style="color:#009900"> (HttpURLConnection) url.openConnection(); //创建实例,用于接受和发送数据</span></code></span>
- 1
【1】HttpURLConnection接受数据
子线程更新UI:
默认原则:子线程一般不更新UI(Android4.0之后默认的),一般只有主线程才可以更新UI
1.使用Handler更新:
<span style="color:#000000"><code><span style="color:#880000">//创建handler 对象,当实例handler调用sendmessage的方法时候自动调用handlemaess方法</span>
<span style="color:#000088">private</span> Handler handler = <span style="color:#000088">new</span> Handler(){
<span style="color:#880000">//处理消息 </span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">handleMessage</span>(android.os.Message msg) {
Bitmap bitmap = (Bitmap) msg.obj; <span style="color:#880000">//obj是吸纳任何变量类型的,吸了什么类型取出来就强制转为什么类型</span>
iv.setImageBitmap(bitmap);
};
};</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2.使用runOnUiThread()进行更新也可以
注意:这句api 不 管你在什么位置上(不管是在主线程还是子线程里),调用 action都运行在UI线程里
<span style="color:#000000"><code>runOnUiThread(<span style="color:#000088">new</span> Runnable() {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
iv.setImageBitmap(cacheBitmap); <span style="color:#880000">//更新图片UI,调用runOnUiThread API函数</span>
}
});</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Handler对比runOnUiThread
[1]如果仅仅更新ui,那么使用runOnUiThread就可以了
[2]有时候通过Handler发送消息的时候需要携带数据,那么仅能使用Handler了
Handler的api介绍:
[1] postDelayed函数
<span style="color:#000000"><code><span style="color:#880000">//5秒钟后 执行run方法</span>
<span style="color:#000088">new</span> Handler().postDelayed(<span style="color:#000088">new</span> Runnable() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
tv.setText(<span style="color:#009900">"哈哈哈哈哈"</span>);
}
}, <span style="color:#006666">5000</span>);
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
PS:java中也有类似的方法TimerTask:
<span style="color:#000000"><code>Timer timer = <span style="color:#000088">new</span> Timer();
TimerTask task=<span style="color:#000088">new</span> TimerTask() {
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
<span style="color:#880000">// TODO Auto-generated method stub</span>
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"我是Java方法实现的"</span>);
}
};
<span style="color:#880000">//五秒后执行task</span>
timer.schedule(task, <span style="color:#006666">5000</span>);
<span style="color:#880000">//3秒后 每隔1秒执行一次run方法</span>
timer.schedule(task, <span style="color:#006666">3000</span>,<span style="color:#006666">1000</span>);
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
当Java中的TimerTask方法使用每个几秒执行一次的方法时候注意一下,如果不销毁,即使你退出了 程序,但他依旧在后台执行活动,记得在销毁活动Activity的时候把TimerTask销毁
<span style="color:#000000"><code><span style="color:#880000">//当Activity销毁的时候 会执行这个方法</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onDestroy</span>() {
timer.cancel(); <span style="color:#880000">//销毁timer</span>
task.cancel(); <span style="color:#880000">//销毁 </span>
<span style="color:#000088">super</span>.onDestroy();
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
对比:Handler延时api可以更新UI,但是TimerTask不可以更新UI。TimerTask中内置runOnUiThread这个api才可以更新UI
开源项目smartimageview介绍
[1]把com包源码拷贝到当前工程
[2]在使用smartimageview类的时候,在布局里面定义的时候一定是这个类的完整包名+类名
api:应用程序界面(接口)
【2】HttpURLConnection发送数据(向服务器提交数据)
问:基于什么协议? 答:http协议
get方式:组拼url地址把数据到url显示,get方式提交数据大小限制:1kb(浏览器规定),4kb(http协议规定)
post方式:post方式提交安全
get跟post方式的区别:
1.请求路径不同:get方式url直接在后面带数据,post方式通过把请求体的方式把数据发给服务器(以流的形式写给服务器)
2.post方式要自己组拼请求体的内容
3.post方式比get方式多了2个头信息 content-length以及content-type
get方式:
<span style="color:#000000"><code>
<span style="color:#000088">new</span> Thread() {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
<span style="color:#000088">try</span> {
<span style="color:#880000">// [2]获取用户名和密码</span>
String name = et_username.getText().toString().trim();
String pwd = et_password.getText().toString().trim();
<span style="color:#880000">// [2.1]定义get方式要提交的路径 小细节 如果提交中文要对name 和 pwd 进行一个urlencode</span>
<span style="color:#880000">// 编码</span>
String path = <span style="color:#009900">"http://192.168.1.235:8080/login/LoginServlet?username="</span>
+ URLEncoder.encode(name, <span style="color:#009900">"utf-8"</span>) + <span style="color:#009900">"&password="</span> + URLEncoder.encode(pwd, <span style="color:#009900">"utf-8"</span>) + <span style="color:#009900">""</span>;
<span style="color:#880000">// (1) 创建一个url对象 参数就是网址</span>
URL url = <span style="color:#000088">new</span> URL(path);
<span style="color:#880000">// (2)获取HttpURLConnection 链接对象</span>
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
<span style="color:#880000">// (3)设置参数 发送get请求</span>
conn.setRequestMethod(<span style="color:#009900">"GET"</span>); <span style="color:#880000">// 默认请求 就是get 要大写</span>
<span style="color:#880000">// (4)设置链接网络的超时时间</span>
conn.setConnectTimeout(<span style="color:#006666">5000</span>);
<span style="color:#880000">// (4.2)设置网络读取的超时时间</span>
conn.setReadTimeout(<span style="color:#006666">5000</span>);
<span style="color:#880000">// (4.3)连接</span>
conn.connect();
<span style="color:#880000">// (5)获取服务器返回的状态码</span>
<span style="color:#000088">int</span> code = conn.getResponseCode(); <span style="color:#880000">// 200 代表获取服务器资源全部成功</span>
<span style="color:#880000">// 206请求部分资源</span>
<span style="color:#000088">if</span> (code == <span style="color:#006666">200</span>) {
<span style="color:#880000">// (6)获取服务器返回的数据 以流的形式返回</span>
InputStream inputStream = conn.getInputStream();
<span style="color:#880000">// (6.1)把inputstream 转换成 string</span>
String content = StreamTools.readStream(inputStream);
<span style="color:#880000">// (7)把服务器返回的数据展示到Toast上 不能在子线程展示toast</span>
showToast(content);
}
} <span style="color:#000088">catch</span> (Exception e) {
e.printStackTrace();
}
};
}.start();</code></span>
- 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
- 39
post方式:
<span style="color:#000000"><code> <span style="color:#006666">new</span> <span style="color:#000088">Thread</span>() {
<span style="color:#000088">public</span> <span style="color:#006666">void</span> run() {
try {
<span style="color:#880000">// [2]获取用户名和密码</span>
<span style="color:#4f4f4f">String</span> name <span style="color:#4f4f4f">=</span> et_username<span style="color:#4f4f4f">.</span>getText()<span style="color:#4f4f4f">.</span>toString()<span style="color:#4f4f4f">.</span>trim();
<span style="color:#4f4f4f">String</span> pwd <span style="color:#4f4f4f">=</span> et_password<span style="color:#4f4f4f">.</span>getText()<span style="color:#4f4f4f">.</span>toString()<span style="color:#4f4f4f">.</span>trim();
<span style="color:#880000">// [2.1]定义get方式要提交的路径</span>
<span style="color:#4f4f4f">String</span> <span style="color:#4f4f4f">data</span> <span style="color:#4f4f4f">=</span> <span style="color:#009900">"username="</span> <span style="color:#4f4f4f">+</span> URLEncoder<span style="color:#4f4f4f">.</span>encode(name, <span style="color:#009900">"utf-8"</span>) <span style="color:#4f4f4f">+</span> <span style="color:#009900">"&password="</span>
<span style="color:#4f4f4f">+</span> URLEncoder<span style="color:#4f4f4f">.</span>encode(pwd, <span style="color:#009900">"utf-8"</span>) <span style="color:#4f4f4f">+</span> <span style="color:#009900">""</span>; <span style="color:#880000">// 请求体的内容</span>
<span style="color:#880000">// 一 ☆☆☆☆☆☆☆和get方式提交数据 区别 路径不同</span>
<span style="color:#4f4f4f">String</span> path <span style="color:#4f4f4f">=</span> <span style="color:#009900">"http://192.168.1.235:8080/login/LoginServlet"</span>;
<span style="color:#880000">// (1) 创建一个url对象 参数就是网址</span>
URL url <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> URL(path);
<span style="color:#880000">// (2)获取HttpURLConnection 链接对象</span>
HttpURLConnection conn <span style="color:#4f4f4f">=</span> (HttpURLConnection) url<span style="color:#4f4f4f">.</span>openConnection();
<span style="color:#880000">// (3)设置参数 发送post请求</span>
<span style="color:#880000">// 二 ☆☆☆☆☆☆☆和get方式提交数据 区别 设置请求方式是post</span>
conn<span style="color:#4f4f4f">.</span>setRequestMethod(<span style="color:#009900">"POST"</span>); <span style="color:#880000">// 默认请求 就是get 要大写</span>
<span style="color:#880000">// (4)设置链接网络的超时时间</span>
conn<span style="color:#4f4f4f">.</span>setConnectTimeout(<span style="color:#006666">5000</span>);
<span style="color:#880000">// 三 ☆☆☆☆☆☆☆和get方式提交数据 区别 要多设置2个请求头信息</span>
<span style="color:#880000">// 设置头信息</span>
conn<span style="color:#4f4f4f">.</span>setRequestProperty(<span style="color:#009900">"Content-Type"</span>, <span style="color:#009900">"application/x-www-form-urlencoded"</span>);
conn<span style="color:#4f4f4f">.</span>setRequestProperty(<span style="color:#009900">"Content-Length"</span>, <span style="color:#4f4f4f">data</span><span style="color:#4f4f4f">.</span>length() <span style="color:#4f4f4f">+</span> <span style="color:#009900">""</span>);
<span style="color:#880000">// 四 ☆☆☆☆☆☆☆ 把我们组拼好的数据提交给服务器 以流的形式提交</span>
conn<span style="color:#4f4f4f">.</span>setDoOutput(<span style="color:#006666">true</span>);<span style="color:#880000">// 设置一个标记 允许输出</span>
conn<span style="color:#4f4f4f">.</span>getOutputStream()<span style="color:#4f4f4f">.</span>write(<span style="color:#4f4f4f">data</span><span style="color:#4f4f4f">.</span>getBytes());
<span style="color:#880000">// (5)获取服务器返回的状态码</span>
int code <span style="color:#4f4f4f">=</span> conn<span style="color:#4f4f4f">.</span>getResponseCode();
<span style="color:#880000">// 200 代表获取服务器资源全部成功 206请求部分资源</span>
<span style="color:#000088">if</span> (code <span style="color:#4f4f4f">==</span> <span style="color:#006666">200</span>) {
<span style="color:#880000">// (6)获取服务器返回的数据 以流的形式返回</span>
InputStream inputStream <span style="color:#4f4f4f">=</span> conn<span style="color:#4f4f4f">.</span>getInputStream();
<span style="color:#880000">// (6.1)把inputstream 转换成 string</span>
<span style="color:#4f4f4f">String</span> content <span style="color:#4f4f4f">=</span> StreamTools<span style="color:#4f4f4f">.</span>readStream(inputStream);
<span style="color:#880000">// (7)把服务器返回的数据展示到Toast上 不能在子线程展示toast</span>
showToast(content);
}
} catch (Exception e) {
e<span style="color:#4f4f4f">.</span>printStackTrace();
}
};
}<span style="color:#4f4f4f">.</span>start();</code></span>
- 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
- 39
- 40
- 41
- 42
- 43
Httpclient向服务器提交数据:
get方式:
<span style="color:#000000"><code> <span style="color:#880000">// [2.1]定义get方式要提交的路径 小细节 如果提交中文要对name 和 pwd 进行一个urlencode 编码</span>
String path = <span style="color:#009900">"http://192.168.1.235:8080/login/LoginServlet?username="</span> + URLEncoder.encode(name, <span style="color:#009900">"utf-8"</span>)
+ <span style="color:#009900">"&password="</span> + URLEncoder.encode(pwd, <span style="color:#009900">"utf-8"</span>) + <span style="color:#009900">""</span>;
<span style="color:#880000">// [3]获取httpclient实例</span>
DefaultHttpClient client = <span style="color:#000088">new</span> DefaultHttpClient();
<span style="color:#880000">// [3.1]准备get请求 定义 一个httpget实现</span>
HttpGet <span style="color:#000088">get</span> = <span style="color:#000088">new</span> HttpGet(path);
<span style="color:#880000">// [3.2]执行一个get请求</span>
HttpResponse response = client.execute(<span style="color:#000088">get</span>);
<span style="color:#880000">// [4]获取服务器返回的状态码</span>
<span style="color:#000088">int</span> code = response.getStatusLine().getStatusCode();
<span style="color:#000088">if</span> (code == <span style="color:#006666">200</span>) {
<span style="color:#880000">// [5]获取服务器返回的数据 以流的形式返回</span>
InputStream inputStream = response.getEntity().getContent();
<span style="color:#880000">// [6]把流转换成字符串</span>
String content = StreamTools.readStream(inputStream);
<span style="color:#880000">// [7]展示结果</span>
showToast(content);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
post方式:
<span style="color:#000000"><code> <span style="color:#880000">// [2]获取用户名和密码</span>
<span style="color:#4f4f4f">String</span> name <span style="color:#4f4f4f">=</span> et_username<span style="color:#4f4f4f">.</span>getText()<span style="color:#4f4f4f">.</span>toString()<span style="color:#4f4f4f">.</span>trim();
<span style="color:#4f4f4f">String</span> pwd <span style="color:#4f4f4f">=</span> et_password<span style="color:#4f4f4f">.</span>getText()<span style="color:#4f4f4f">.</span>toString()<span style="color:#4f4f4f">.</span>trim();
<span style="color:#4f4f4f">String</span> path <span style="color:#4f4f4f">=</span> <span style="color:#009900">"http://192.168.11.73:8080/login/LoginServlet"</span>;
<span style="color:#880000">// [3]以httpClient 方式进行post 提交</span>
DefaultHttpClient client <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> DefaultHttpClient();
<span style="color:#880000">// [3.1]准备post 请求</span>
HttpPost post <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> HttpPost(path);
<span style="color:#880000">// [3.1.0]准备parameters</span>
<span style="color:#4f4f4f">List</span><span style="color:#4f4f4f"><</span>NameValuePair<span style="color:#4f4f4f">></span> lists <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> ArrayList<span style="color:#4f4f4f"><</span>NameValuePair<span style="color:#4f4f4f">></span>();
<span style="color:#880000">// [3.1.1]准备 NameValuePair 实际上就是我们要提交的用户名 和密码 key是服务器key :username</span>
BasicNameValuePair nameValuePair <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> BasicNameValuePair(<span style="color:#009900">"username"</span>, name);
BasicNameValuePair pwdValuePair <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> BasicNameValuePair(<span style="color:#009900">"password"</span>, pwd);
<span style="color:#880000">// [3.1.3] 把nameValuePair 和 pwdValuePair 加入到集合中</span>
lists<span style="color:#4f4f4f">.</span>add(nameValuePair);
lists<span style="color:#4f4f4f">.</span>add(pwdValuePair);
<span style="color:#880000">// [3.1.3]准备entity</span>
UrlEncodedFormEntity entity <span style="color:#4f4f4f">=</span> <span style="color:#006666">new</span> UrlEncodedFormEntity(lists);
<span style="color:#880000">// [3.2]准备post方式提交的正文 以实体形式准备 (键值对形式 )</span>
post<span style="color:#4f4f4f">.</span>setEntity(entity);
HttpResponse response <span style="color:#4f4f4f">=</span> client<span style="color:#4f4f4f">.</span>execute(post);
<span style="color:#880000">// [4]获取服务器返回的状态码</span>
int code <span style="color:#4f4f4f">=</span> response<span style="color:#4f4f4f">.</span>getStatusLine()<span style="color:#4f4f4f">.</span>getStatusCode();
<span style="color:#000088">if</span> (code <span style="color:#4f4f4f">==</span> <span style="color:#006666">200</span>) {
<span style="color:#880000">// [5]获取服务器返回的数据 以流的形式返回</span>
InputStream inputStream <span style="color:#4f4f4f">=</span> response<span style="color:#4f4f4f">.</span>getEntity()<span style="color:#4f4f4f">.</span>getContent();
<span style="color:#880000">// [6]把流转换成字符串</span>
<span style="color:#4f4f4f">String</span> content <span style="color:#4f4f4f">=</span> StreamTools<span style="color:#4f4f4f">.</span>readStream(inputStream);
<span style="color:#880000">// [7]展示结果</span>
showToast(content);
}</code></span>
- 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
Async-Httpclient开源项目向服务器提交数据:
快速Android开发系列网络篇之Android-Async-Http - AngelDevil - 博客园
get方式:
<span style="color:#000000"><code>
<span style="color:#880000">// [3]使用开源项目进行get请求</span>
<span style="color:#880000">// [3.1]创建asynchttpclient</span>
AsyncHttpClient client = <span style="color:#000088">new</span> AsyncHttpClient();
<span style="color:#880000">// [3.2]进行get 请求</span>
client.get(path, <span style="color:#000088">new</span> AsyncHttpResponseHandler() {
<span style="color:#880000">// 请求成功的回调方法</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onSuccess</span>(<span style="color:#000088">int</span> statusCode, Header[] headers, <span style="color:#000088">byte</span>[] responseBody) {
<span style="color:#000088">try</span> {
Toast.makeText(getApplicationContext(), <span style="color:#000088">new</span> String(responseBody, <span style="color:#009900">"gbk"</span>), <span style="color:#006666">1</span>).show();
} <span style="color:#000088">catch</span> (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
<span style="color:#880000">// 请求失败</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onFailure</span>(<span style="color:#000088">int</span> statusCode, Header[] headers, <span style="color:#000088">byte</span>[] responseBody, Throwable error) {
}
});
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
post方式:
<span style="color:#000000"><code> <span style="color:#880000">// [3.1]创建asynchttpclient</span>
AsyncHttpClient client = <span style="color:#000088">new</span> AsyncHttpClient();
<span style="color:#880000">// [3.1.0]准备请求体的内容</span>
RequestParams <span style="color:#000088">params</span> = <span style="color:#000088">new</span> RequestParams();
<span style="color:#000088">params</span>.put(<span style="color:#009900">"username"</span>, name);
<span style="color:#000088">params</span>.put(<span style="color:#009900">"password"</span>, pwd);
<span style="color:#880000">// [3.2]进行post请求 params 请求的参数封装</span>
client.post(path, <span style="color:#000088">params</span>, <span style="color:#000088">new</span> AsyncHttpResponseHandler() {
<span style="color:#880000">// 请求成功 登录成功</span>
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onSuccess</span>(<span style="color:#000088">int</span> statusCode, Header[] headers, <span style="color:#000088">byte</span>[] responseBody) {
<span style="color:#000088">try</span> {
Toast.makeText(getApplicationContext(), <span style="color:#000088">new</span> String(responseBody, <span style="color:#009900">"gbk"</span>), <span style="color:#006666">1</span>).show();
} <span style="color:#000088">catch</span> (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onFailure</span>(<span style="color:#000088">int</span> statusCode, Header[] headers, <span style="color:#000088">byte</span>[] responseBody, Throwable error) {
}
});</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
PS:请求成功仅仅是服务器有响应,登录成功指的是你输入的账号密码与服务器中的一组账号密码匹配成功
总结:
【1】HttpURLConnection:可以带请求数据,如实现断点下载传输等
【2】Httpclient:很少人用,几乎没有人使用
【3】Async-Httpclient开源项目:仅仅是传一些账号密码用它更方便
多线程下载:
JavaSE多线程下载:
设置请求服务器文件的位置:
<span style="color:#000000"><code>//设置一个请求<span style="color:#4f4f4f">Range</span>,作用就是告诉服务器每个线程下载的开始位置以及结束位置
conn.set<span style="color:#4f4f4f">RequestProperty</span>(<span style="color:#009900">"Range"</span>, <span style="color:#009900">"bytes="</span>+start<span style="color:#4f4f4f">Index</span>+<span style="color:#009900">"-"</span>+<span style="color:#000088">end</span><span style="color:#4f4f4f">Index</span>);</code></span>
- 1
- 2
多线程加速下载:
【1】不是说线程开的越多下载就快(手机迅雷建议开3-4个线程就好)
【2】还受服务器带宽的影响
【3】更多的cpu资源给了你
实现断点续传:
就是把当前线程下载的位置给存起来,下次再下载的时候就按照上次下载的位置继续下载就可以了
开源项目实现断点续传(xutiles):
Xutils使用方法:http://blog.csdn.net/dj0379/article/details/38356773/
四大组件
PS:
1.四大组件的定义方式都是一样的,都需要在清单文件配置一下
2.意图是四大组件的纽带
Activity 显示界面
[1] 安卓的四大组件都需要在清单文件AndroidManifest.xml配置(xml中注释快捷键Ctrl+shift+/)
[2] 如果你想让你的应用有多个启动图标,你的activity需要这样配置
<span style="color:#000000"><code><span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.action.MAIN"</span> /></span> <span style="color:#880000"><!--MAIN代表主入口 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">category</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.category.LAUNCHER"</span> /></span> <span style="color:#880000"><!-- LAUNCHER代表启动 --></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span></code></span>
- 1
- 2
- 3
- 4
[3] activity的icon以及label可以自定义,没有指定的话默认使用application中的icon和label
[4]一个安卓应用一般配置一个启动图标就可以了,多的话不仅是用户桌面繁琐
意图:
Android学习之Intent使用 - zhouhb - 博客园
意图就是我要完成一件事
隐式意图:
定义:通过一组动作或者数据
<span style="color:#000000"><code>// [<span style="color:#006666">4</span>]设置数据,This method automatically clears any type that was previously <span style="color:#000088">set</span> by setType.
// intent<span style="color:#009900">.setData</span>(Uri<span style="color:#009900">.parse</span>(<span style="color:#009900">"itheima1:"</span>+<span style="color:#006666">110</span>))<span style="color:#880000">;</span>
// [<span style="color:#006666">5</span>]设置数据类型,This method automatically clears any data that was previously <span style="color:#000088">set</span> by setData.
// intent<span style="color:#009900">.setType</span>(<span style="color:#009900">"aa/bb1"</span>)<span style="color:#880000">;</span>
// [<span style="color:#006666">6</span>]注意 小细节☆ 如果setdata 方法和 settype 方法一起使用的时候 应该使用下面这个方法
intent<span style="color:#009900">.setDataAndType</span>(Uri<span style="color:#009900">.parse</span>(<span style="color:#009900">"itheima1:"</span> + <span style="color:#006666">110</span>), <span style="color:#009900">"aa/bb1"</span>)<span style="color:#880000">;</span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
显式意图:
定义:通过指定具体的包名(在项目的AndroidMainfest.xml里面)和类名
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮跳转到 TestActivity</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click3</span>(View v) {
<span style="color:#880000">// [1]创建意图对象 意图就是我要完成一件事</span>
Intent intent = <span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>, Test3Activity.class);
<span style="color:#880000">// [2]设置包名和类名 packageName:当前应用的包名</span>
<span style="color:#880000">// intent.setClassName("com.itheima.newactivity",</span>
<span style="color:#880000">// "com.itheima.newactivity.Test3Activity");</span>
<span style="color:#880000">// [3]开启Activity</span>
startActivity(intent);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
总结:
1.开启自己应用的界面用显式意图
2.开启其他应用(如系统应用)用隐式意图
3.显式意图安全一些
Activity生命图解
两分钟彻底让你明白Android Activity生命周期(图文)! - Android_Tutor的专栏 - 博客频道 - CSDN.NET
横竖屏切换Activity的生命周期:
快捷键:Ctrl+F11
android:screenOrientation=”portrait” 代表竖屏
android:screenOrientation=”landscape” 代表横屏
栈:先进后出
队列:先进先出
task 什么叫任务
[1]打开一个Activity叫进栈 关闭一个Activity叫出栈
[2]我们操作的Activity永远是栈顶的Activity
[3]任务栈是用来维护用户操作体验的
[4]应用程序退出了是任务栈清空了
[5]一般情况一个应用程序对应一个任务栈
Activity的四种启动模式
<span style="color:#000000"><code>android:launchMode="standard" <span style="color:#880000"><!--配置Activity启动模式--></span></code></span>
- 1
1、对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。
例如A启动A,A再接着启动A,A继续启动A,然后再分别出栈,如图所示
2、当活动的启动模式指定为 singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
3、当活动的启动模式指定为 singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
4、使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。
假设B启动A,A启动C,其中A的启动模式为singleInstance,则:
返回的页面顺序是C-B-A
转载请注明:Android开发中文站 » Activity的四种启动模式-图文并茂
### Broadcast Receiver 广播 背景:Android系统已经定义好了一些广播事件,比如外拨电话、短信到来、sd状态,电池电量。。。Android开发者使用Broadcast Receiver 广播去接收系统已经定义好的这些事件 #### 不同版本广播的特点: [1]在4.0 谷歌工程师要求 第一次安装应用的时候必须有的界面 这样的广播接受者才生效 [2]在设置页面有一个强行停止的按钮 如果说用户点击了 强行停止按钮那么广播接收者也不生效 [3]在2.3的手机上没有这样的安全设计 广播接收者的一般步骤: [1]定义广播接收者 相当于你买了一个收音机  [2]在清单文件里配置 相当于你装了一块电池  [3]具体 调节到了合适的频道  注意事项: 1.接收系统电话的广播需要用到权限android.permission.PROCESS_OUTGOING_CALLS 2.监听sd卡状态的时候,需要在清单配置
<span style="color:#000000"><code><span style="color:#880000"><!--小细节 这里需要配置一个data 约束类型叫file 因为sd里面存的数据类型是file --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">data</span> <span style="color:#4f4f4f">android:scheme</span>=<span style="color:#009900">"file"</span>/></span></code></span>
- 1
- 2
系统广播:
短信监听实例:
[1]在清单文件的配置
<span style="color:#000000"><code><span style="color:#880000"><!--监听短信需要配置以下,但Google在adt21之后取消了,需要自己复制进去 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.smslistener.SmsListenerReceiver"</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.provider.Telephony.SMS_RECEIVED"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.具体实现代码
<span style="color:#000000"><code><span style="color:#880000">//当短信到来的时候执行 </span>
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">//获取发送者的号码 和发送内容 pdus是固定写法来的</span>
Object []objects = (Object[]) intent.getExtras().<span style="color:#000088">get</span>(<span style="color:#009900">"pdus"</span>);
<span style="color:#000088">for</span> (Object obj : objects) {
<span style="color:#880000">//[1]获取smsmessage实例 </span>
SmsMessage smsMessage = SmsMessage.createFromPdu((<span style="color:#000088">byte</span>[]) obj);
<span style="color:#880000">//[2]获取发送短信的内容 </span>
String messageBody = smsMessage.getMessageBody();<span style="color:#880000">//获得发来短信的内容</span>
String address = smsMessage.getOriginatingAddress();<span style="color:#880000">//获得短信的发送者的手机号码</span>
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"body:"</span>+messageBody+<span style="color:#009900">"-----"</span>+address);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
[3]加上权限android.permission.RECEIVE_SMS
应用卸载安装监听案例
[1]在清单文件配置:
<span style="color:#000000"><code> <span style="color:#880000"><!-- "android.intent.action.PACKAGE_INSTALL"没有任何意义,只是谷歌工程师预留的,还没有被使用 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.appstate.AppStateReceiver"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.action.PACKAGE_INSTALL"</span> /></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.action.PACKAGE_ADDED"</span> /></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.action.PACKAGE_REMOVED"</span> /></span>
<span style="color:#880000"><!-- 想让action事件生效 还需要 配置一个data --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">data</span> <span style="color:#4f4f4f">android:scheme</span>=<span style="color:#009900">"package"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
[2]实现代码
<span style="color:#000000"><code><span style="color:#880000">//当有新的应用被安装 了 或者有应用被卸载 了 这个方法调用 </span>
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">//获取当前广播事件类型 </span>
String action = intent.getAction();
<span style="color:#000088">if</span> (<span style="color:#009900">"android.intent.action.PACKAGE_INSTALL"</span>.equals(action)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"应用安装了11111"</span>);
}<span style="color:#000088">else</span> <span style="color:#000088">if</span> (<span style="color:#009900">"android.intent.action.PACKAGE_ADDED"</span>.equals(action)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"应用安装了22222"</span>);
}<span style="color:#000088">else</span> <span style="color:#000088">if</span>(<span style="color:#009900">"android.intent.action.PACKAGE_REMOVED"</span>.equals(action)){
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"应用卸载了"</span>+intent.getData());
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
注意:在Broadcast Receiver 广播中,有两个在配置清单文件中需要配置data数据的,一个是监听发来的短信(需要配置为了file),一个是监听应用卸载安装(需要配置为”package”)
系统重启广播案例:
注意:不能直接在广播接收者中开启Activity
[1]在清单文件配置:
<span style="color:#000000"><code><span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.bootreceiver.BootReceiver"</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"android.intent.action.BOOT_COMPLETED"</span>/></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span></code></span>
- 1
- 2
- 3
- 4
- 5
[2]实现代码
<span style="color:#000000"><code><span style="color:#880000">// 当手机重新启动的时候调用</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">// 在这个方法里面开启activity</span>
Intent intent2 = <span style="color:#000088">new</span> Intent(context, MainActivity.class);
<span style="color:#880000">// ☆☆☆注意 不能在广播接收者里面直接开启activity 需要添加一个标记 添加一个任务栈的标记</span>
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
<span style="color:#880000">// 开启activity</span>
context.startActivity(intent2);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
[3]加上权限:android.permission.RECEIVE_BOOT_COMPLETED
ps:屏蔽返回键的方法
<span style="color:#000000"><code>@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onBackPressed</span>() { <span style="color:#880000">//主要实现返回键的功能</span>
<span style="color:#880000">// TODO Auto-generated method stub</span>
<span style="color:#880000">// super.onBackPressed();//父类主要实现了finish(),我们想屏蔽它,就不让它调用父类方法就好</span>
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"已经屏蔽了返回键"</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
自定义广播:
参考:android有序广播和无序广播的区别 - ljb_blog的专栏 - 博客频道 - CSDN.NET
1.有序广播
是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。
BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。
可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。
有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。如果多个应用程序设置的优先级别相同,则谁先注册的广播,谁就可以优先接收到广播。
这里接收短信的广播是有序广播,因此可以设置你自己的广播接收器的级别高于系统原来的级别,就可以拦截短信,并且不存收件箱,也不会有来信提示音。
类似中央发送红头文件,一级一级往下发,各个单位按照优先级接受,省级->县级->乡镇
[1]发送广播
<span style="color:#000000"><code><span style="color:#880000">//点击按钮 发送有序广播 发大米</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click</span>(View v) {
Intent intent = <span style="color:#000088">new</span> Intent();
intent.setAction(<span style="color:#009900">"com.xinwen"</span>);
<span style="color:#880000">/**
* intent 意图 '
*
* receiverPermission 接收的权限
*
* resultReceiver 最终的receiver
*
* scheduler handler
*
* initialCode 初始码
* initialData 初始化数据
*/</span>
sendOrderedBroadcast(intent, <span style="color:#000088">null</span>, <span style="color:#000088">new</span> FinalReceiver(), <span style="color:#000088">null</span>,
<span style="color:#006666">1</span>, <span style="color:#009900">"习大大给每个村民发了1000斤大米"</span>, <span style="color:#000088">null</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
FinalReceiver广播主要代码:
<span style="color:#000000"><code><span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">//[1]获取发送广播携带的数据</span>
String content= getResultData();
<span style="color:#880000">//[2]显示结果</span>
Toast.makeText(context, <span style="color:#009900">"报告习大大:"</span>+content, <span style="color:#006666">1</span>).show();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
[2]广播接收者
清单文件配置:priority配置的值越大,越优先进行
<span style="color:#000000"><code><span style="color:#880000"><!-- priority配置的值越大,越优先进行 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.example.receiverxixi.ProviceReceiver"</span> ></span> <span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> <span style="color:#4f4f4f">android:priority</span>=<span style="color:#009900">"1000"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.xinwen"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.example.receiverxixi.CityReceiver"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> <span style="color:#4f4f4f">android:priority</span>=<span style="color:#009900">"100"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.xinwen"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.example.receiverxixi.CountryReceiver"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> <span style="color:#4f4f4f">android:priority</span>=<span style="color:#009900">"50"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.xinwen"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.example.receiverxixi.NongMinReceiver"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> <span style="color:#4f4f4f">android:priority</span>=<span style="color:#009900">"-100"</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.xinwen"</span> /></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
ProviceReceiver主要实现代码:
<span style="color:#000000"><code><span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">// [1]获取发送广播携带的数据</span>
String content = getResultData();
<span style="color:#880000">// [2]显示结果</span>
Toast.makeText(context, <span style="color:#009900">"省:"</span> + content, <span style="color:#006666">1</span>).show();
<span style="color:#880000">// [2.1]终止广播,省级以下的官员都不可以接收广播了,但FinalReceiver钦差大人可以可以接收</span>
abortBroadcast();
<span style="color:#880000">// [3]修改数据,因为有了abortBroadcast,所以省级以下官员不可以接收广播了,但钦差大人可以接收这个修改的广播</span>
setResultData(<span style="color:#009900">"习大大给每个村民发了500斤大"</span>);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.无序广播 (普通广播)
通过Context.sendBroadcast()方法来发送,它是完全异步的。
所有的receivers(接收器)的执行顺序不确定,因此所有的receivers(接收器)接收broadcast的顺序不确定。
这种方式效率更高,但是BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API
比如新闻联播.每天晚上7:00开播(我不管你看还是不看)
[1]按钮发送广播
<span style="color:#000000"><code><span style="color:#880000">//点击按钮 发送一条无序广播 </span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click</span>(View v) {
<span style="color:#880000">//创建一个意图 </span>
Intent intent = <span style="color:#000088">new</span> Intent();
<span style="color:#880000">//设置发送广播的动作,相当于发送了一条红包口令 </span>
intent.setAction(<span style="color:#009900">"com.itheima.custom"</span>);
<span style="color:#880000">//Intent意图里面携带了名字为"name"的数据 </span>
intent.putExtra(<span style="color:#009900">"name"</span>, <span style="color:#009900">"新闻联播每天晚上 7点准时开整!!"</span>);
<span style="color:#880000">//发送无序按钮 </span>
sendBroadcast(intent);<span style="color:#880000">//发送无序广播</span>
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
[2]接受无序广播的工程
在清单文件的配置:
<span style="color:#000000"><code><span style="color:#880000"><!--action里面的name相当于红包口令 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">receiver</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.receivewuxubroadcast.ReceiveCustomReceiver"</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">intent-filter</span> ></span>
<span style="color:#006666"><<span style="color:#4f4f4f">action</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.custom"</span>/></span>
<span style="color:#006666"></<span style="color:#4f4f4f">intent-filter</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">receiver</span>></span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
主要实现代码:
<span style="color:#000000"><code><span style="color:#880000">//当接收到我们发送的自定义广播</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">//[1]获取发送广播携带的数据 </span>
String content = intent.getStringExtra(<span style="color:#009900">"name"</span>);
Toast.makeText(context, content, <span style="color:#006666">1</span>).show();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
有序广播对比无序广播:
[1]有序广播可以终止,有序广播数据可以被修改
[2]无序广播不可以被终止以及数据不可以被修改
特殊的广播接收者:
操作特别频繁的广播事件 比如:屏幕的锁屏和解锁,电池电量的变化 这种事件的广播在清单文件里注册无效的
注册广播接收者的两种方式:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the tag in your AndroidManifest.xml.
[1]动态注册 通过代码方式注册
[2]在清单文件通过receiver tag节点静态发布的(这个办法对于特殊的广播接收者无效)
锁屏解锁的案例
1.在ScreenReceiver广播里面
<span style="color:#000000"><code><span style="color:#880000">//当我们进行屏幕锁屏和解锁 这个方法执行 </span>
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onReceive</span>(Context context, Intent intent) {
<span style="color:#880000">//获取当前广播的事件类型 </span>
String action = intent.getAction();
<span style="color:#000088">if</span>(<span style="color:#009900">"android.intent.action.SCREEN_OFF"</span>.equals(action)){
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"屏幕锁屏了 "</span>);
}<span style="color:#000088">else</span> <span style="color:#000088">if</span> (<span style="color:#009900">"android.intent.action.SCREEN_ON"</span>.equals(action)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"屏幕解锁了"</span>);
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2.在MainActivity中的代码:
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MainActivity</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Activity</span> {
<span style="color:#000088">private</span> ScreenReceiver screenReceiver;
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle savedInstanceState) {
<span style="color:#000088">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<span style="color:#880000">//动态的去注册广播接收者 </span>
screenReceiver = <span style="color:#000088">new</span> ScreenReceiver();
<span style="color:#880000">//创建IntentFilter 对象</span>
IntentFilter filter = <span style="color:#000088">new</span> IntentFilter();
<span style="color:#880000">//添加要注册的action</span>
filter.addAction(<span style="color:#009900">"android.intent.action.SCREEN_OFF"</span>);
filter.addAction(<span style="color:#009900">"android.intent.action.SCREEN_ON"</span>);
<span style="color:#880000">//动态注册广播接收者</span>
registerReceiver(screenReceiver, filter);
}
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onDestroy</span>() {
<span style="color:#880000">//当activity 销毁的时候要取消注册广播接收者 </span>
unregisterReceiver(screenReceiver);
<span style="color:#000088">super</span>.onDestroy();
}</code></span>
- 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
发送接收数据需要注意的选项:
1.我们定义Intent的方法来发送数据,那么接受它的数据的时候也是通过Intent方法来获取的
2.不是通过Intent意图发数据的,那就不要通过Intent意图来接收数据!!!
Service 服务
进程
Android进程与线程基本知识 - Healtheon - 博客园
http://www.cnblogs.com/hanyonglu/archive/2012/04/12/2443262.html
概念:
[1]Android下四大组件都是运行在主线程中
[2]服务是在后台运行的 是没有界面的Activity(Activity 你大爷-> 服务)
进程优先级:
前台线程(Foreground process)>可见线程(Visible process)>服务线程(Service process)>后台线程(Background process)>空线程(Empty process)
Start方式开启服务的特点:
1.第一次点击服按钮开启服务 服务就会onCreate()方法和onStartCommand(Intent intent, int flags, int startId)
ps:服务中的onStartCommand跟Activity中的onStart方法只是名字不同,作用是一样的
2.第二次点击按钮 再次开启服务 服务执行onStartCommand方法
3.服务一旦被开启 服务就会后台长期运行 直到用户手动停止
StartService开启服务的例子:
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 开启服务 通过startservice</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click1</span>(View v) {
Intent intent = <span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>, DemoService.class);
startService(intent); <span style="color:#880000">// 开启服务</span>
}
<span style="color:#880000">// 点击按钮 关闭服务 通过stopService</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click2</span>(View v) {
Intent intent = <span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>, DemoService.class);
stopService(intent);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
bindService开启服务的特点:
1.第一次点击按钮 会执行服务的OnCreate方法和OnBind方法
2.当OnBind方法返回为null的时候,OnServiceConnected方法是不执行的
3.第二次点击按钮 服务没响应
4.不求同时生,但求同时死 指的是调用者(比如Activity)与服务之间的关系
5.服务不可以多次解绑,多次连续解绑会报异常
6.通过bind方法开启服务,服务不能在设置页面找到 相当于是一个隐形的服务
bindService开启服务的例子:
// 点击按钮 绑定服务 开启服务的第二种方式
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click3</span>(View v) {
Intent intent = <span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>, DemoService.class);
<span style="color:#880000">// 连接到DemoService 这个服务</span>
conn = <span style="color:#000088">new</span> MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
<span style="color:#880000">// 点击按钮手动解绑服务</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click4</span>(View v) {
unbindService(conn);
}
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onDestroy</span>() {
<span style="color:#880000">// 当Activity销毁的时候 要解绑服务</span>
unbindService(conn);
<span style="color:#000088">super</span>.onDestroy();
}
<span style="color:#880000">// 定义一个类 用来监视服务的状态</span>
<span style="color:#000088">private</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyConn</span> <span style="color:#000088">implements</span> <span style="color:#4f4f4f">ServiceConnection</span> {
<span style="color:#880000">// 当服务连接成功调用</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onServiceConnected</span>(ComponentName name, IBinder service) {
System.out.println(<span style="color:#009900">"onServiceConnected"</span>);
}
<span style="color:#880000">// 失去连接调用</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onServiceDisconnected</span>(ComponentName name) {
System.out.println(<span style="color:#009900">"onServiceDisconnected"</span>);
}
}</code></span>
- 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
为什么要引入bindService?
是为了调用服务里面的方法
通过bindService方式调用服务里面方法的过程:
1.在服务的内部定义一个方法 让Activity去调用
<span style="color:#000000"><code><span style="color:#880000">// 办证的方法</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">banZheng</span>(<span style="color:#000088">int</span> money) {
<span style="color:#000088">if</span> (money > <span style="color:#006666">1000</span>) {
Toast.makeText(getApplicationContext(), <span style="color:#009900">"我是领导 把证给你办了"</span>, <span style="color:#006666">1</span>).show();
} <span style="color:#000088">else</span> {
Toast.makeText(getApplicationContext(), <span style="color:#009900">"这点钱 还想办事...."</span>, <span style="color:#006666">1</span>).show();
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.在服务的内容定义一个中间人对象(IBinder)
<span style="color:#000000"><code><span style="color:#880000">// [1]定义中间人对象(IBinder)</span>
<span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyBinder</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Binder</span> {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callBanZheng</span>(<span style="color:#000088">int</span> money) {
<span style="color:#880000">// 调用办证的方法</span>
banZheng(money);
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3.把我定义的中间人对象在onBind()方法里面返回
<span style="color:#000000"><code><span style="color:#880000">// 把我定义的中间人对象返回</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> IBinder <span style="color:#009900">onBind</span>(Intent intent) {
<span style="color:#000088">return</span> <span style="color:#000088">new</span> MyBinder();
}</code></span>
- 1
- 2
- 3
- 4
- 5
4.在mainActivity的onCreate方法里面调用BindService的目的是为了获取我们定义的中间人对象
<span style="color:#000000"><code>Intent intent = <span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>,BanZhengService.<span style="color:#000088">class</span>);
<span style="color:#880000">//连接服务 </span>
conn = <span style="color:#000088">new</span> MyConn();<span style="color:#880000">//继承ServiceConnection接口重新的连接成功方法里面获取Service返回的IBinder</span>
bindService(intent, conn, BIND_AUTO_CREATE);
</code></span>
- 1
- 2
- 3
- 4
- 5
5.获取中间人对象
<span style="color:#000000"><code><span style="color:#880000">//监视服务的状态</span>
<span style="color:#000088">private</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyConn</span> <span style="color:#000088">implements</span> <span style="color:#4f4f4f">ServiceConnection</span>{
<span style="color:#880000">//当服务连接成功调用</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onServiceConnected</span>(ComponentName name, IBinder service) {
<span style="color:#880000">//获取中间人对象</span>
myBinder = (MyBinder) service;
}
<span style="color:#880000">//失去连接</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onServiceDisconnected</span>(ComponentName name) {
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
6.拿到中间人的方法就可以调用服务里面的方法
<span style="color:#000000"><code>myBinder.callBanZheng(10000000);//MyBinder myBinder=<span style="color:#009900">new MyBinder();</span></code></span>
- 1
7.当Activity销毁的时候解绑服务
<span style="color:#000000"><code><span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onDestroy</span>() {
<span style="color:#880000">//当activity 销毁的时候 解绑服务 </span>
unbindService(conn);<span style="color:#880000">//MyConn conn=new MyConn();</span>
<span style="color:#000088">super</span>.onDestroy();
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
通过接口方式调用服务里面的方法:
接口可以隐藏代码内部的细节 让程序员暴露自己只想暴露的方法
1.定义一个接口 把想暴露的方法都定义在接口里面
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">interface</span> Iservice {
<span style="color:#880000">//把领导想暴露的方法都定义在接口里</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callBanZheng</span>(<span style="color:#000088">int</span> money);
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callPlayMaJiang</span>();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
2.我们定义的中间人对象实现我们自己定义的接口
<span style="color:#000000"><code><span style="color:#880000">// [1]定义中间人对象(IBinder)</span>
<span style="color:#000088">private</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyBinder</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Binder</span> <span style="color:#000088">implements</span> <span style="color:#4f4f4f">Iservice</span> {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callBanZheng</span>(<span style="color:#000088">int</span> money) {
<span style="color:#880000">// 调用办证的方法</span>
banZheng(money);
}
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callPlayMaJiang</span>() {
<span style="color:#880000">// 调用playMaJiang 的方法</span>
playMaJiang();
}
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">callXiSangNa</span>() {
<span style="color:#880000">// 调用洗桑拿的方法</span>
洗桑拿();
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
3.在获取中间人对象的时候,需要把类型变为接口名称类型
将myBinder类型改为Iservice(也可以不修改,因为MyBinder继承了Iservice的接口)
StartService和bindService两者区别:
1.StartService服务一旦被开启 服务就会后台长期运行 直到用户手动停止
2.bindService不求同时生,但求同时死 指的是调用者(比如Activity)与服务之间的关系
补充:混合方式开启服务
Android里Service的bindService()和startService()混合使用深入分析 - 博客频道 - CSDN.NET
需求:既想让服务在后台长期运行又想调用服务里面的方法
1.先调用startService方法开启服务 保证服务能够在后台长期运行
2.调用bindService方法 去获取中间人对象
3.调用unbindService 解绑服务(但服务并没有被销毁)
4.调用stopService
aidl服务
本地服务:运行自己应用的服务
远程服务:运行在其他服务的服务,但跟javaweb中servlet没有半毛钱的关系
实现进程间通信 IPC
使用aidl的步骤:
下面是eclipse教程
1.把Iservice.Java文件变成一个aidl文件(修改后缀名即可)
2.aidl这个语言不认识public 把public去掉
3.自动生成一个Iservice.java文件(gen文件夹下),系统会自动帮我们生成一个Stub类,继承了Binder以及Iservice
4.我们自己定义的中间人对象直接继承Stub可即可
5.保证两个应用的aidl文件是同一个(保证aidl所在包的包名相同即可)
PS:图片中的1代表调用应用的项目,2代表被调用应用的项目,当aidl所在的包名相同的时候,系统就会以为他们共享一个文件
6.获取中间人的对象方式不同了
如何在AndroidStudio中使用AIDL - j275183662的博客 - 博客频道 - CSDN.NET
Content Provider 数据通信
作用:使用内容提供者 把私有的数据库内容给暴露出来
内容提供者把数据进行封装然后提供出来,其他应用都是通过内容解析者来访问
实现内容提供者步骤
1.定义一个类继承contentProvider
2.在清单文件里面配置内容提供者
<span style="color:#000000"><code><span style="color:#880000"><!-- 配置内容提供者 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">provider
</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"com.itheima.db.AccountProvider"</span>
<span style="color:#4f4f4f">android:authorities</span>=<span style="color:#009900">"com.itheima.provider"</span> ></span>
<span style="color:#006666"></<span style="color:#4f4f4f">provider</span>></span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
3.写一个静态代码块 添加匹配规则
<span style="color:#000000"><code><span style="color:#880000">//[1]定义一个urimathcher 定义路径匹配器</span>
<span style="color:#000088">private</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> UriMatcher sURIMatcher = <span style="color:#000088">new</span> UriMatcher(UriMatcher.NO_MATCH);
<span style="color:#000088">private</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> <span style="color:#000088">int</span> QUERYSUCESS = <span style="color:#006666">0</span>; <span style="color:#880000">//ctrl + shift + X </span>
<span style="color:#000088">private</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> <span style="color:#000088">int</span> INSERTSUCESS = <span style="color:#006666">1</span>;
<span style="color:#000088">private</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> <span style="color:#000088">int</span> UPDATESUCESS = <span style="color:#006666">2</span>;
<span style="color:#000088">private</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> <span style="color:#000088">int</span> DELETESUCESS = <span style="color:#006666">3</span>;
<span style="color:#000088">private</span> MyOpenHelper myOpenHelper;
<span style="color:#880000">//[2] 定义静态代码块 添加匹配规则 </span>
<span style="color:#000088">static</span>
{
<span style="color:#880000">/**
* authority 注意 这个参数和你在清单文件里面定义的要一样
*
* Url http://www.baidu.com
*
* uri content://com.itheima.provider/query
* content://com.itheima.provider/insert
* content://com.itheima.provider/update
* content://com.itheima.provider/query
*/</span>
sURIMatcher.addURI(<span style="color:#009900">"com.itheima.provider"</span>, <span style="color:#009900">"query"</span>, QUERYSUCESS);
sURIMatcher.addURI(<span style="color:#009900">"com.itheima.provider"</span>, <span style="color:#009900">"insert"</span>, INSERTSUCESS);
sURIMatcher.addURI(<span style="color:#009900">"com.itheima.provider"</span>, <span style="color:#009900">"update"</span>, UPDATESUCESS);
sURIMatcher.addURI(<span style="color:#009900">"com.itheima.provider"</span>, <span style="color:#009900">"delete"</span>, DELETESUCESS);
}
</code></span>
- 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
4.暴露你想暴露的方法(增删改查)
5.在日志logcat中出现这样一段日志 说明你的内容提供者 没有问题
- 其他应用就可以通过内容的解析者去操作数据库
<span style="color:#000000"><code><span style="color:#880000">// 第二种方式 读取数据库</span>
<span style="color:#880000">// 由于 第一个应用里面的私有数据库已经通过内容提供者给暴露出来了 所以可以直接通过内容的解析者进行访问</span>
<span style="color:#880000">// [1]拿到内容的解析者 直接通过上下文获取</span>
Uri uri = Uri.parse(<span style="color:#009900">"content://com.itheima.provider/query"</span>); <span style="color:#880000">// 路径和你定义的路径一样</span>
Cursor cursor = getContentResolver().query(uri, <span style="color:#000088">null</span>, <span style="color:#000088">null</span>, <span style="color:#000088">null</span>, <span style="color:#000088">null</span>);</code></span>
- 1
- 2
- 3
- 4
- 5
短信备份小案例:
Android开发短信备份小例子 - ibey0nd的专栏 - 博客频道 - CSDN.NET
短信备份小案列代码:
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 查询短信数据内容 然后进行备份</span>
public <span style="color:#000088">void</span> click(View v) {
<span style="color:#000088">try</span> {
<span style="color:#880000">// [1]获取xml序列化实例</span>
XmlSerializer serializer = Xml.newSerializer();
<span style="color:#880000">// [2]设置序列化参数</span>
File file = <span style="color:#000088">new</span> File(Environment.getExternalStorageDirectory().getPath(), <span style="color:#009900">"smsBackUp.xml"</span>);
FileOutputStream fos = <span style="color:#000088">new</span> FileOutputStream(file);
serializer.setOutput(fos, <span style="color:#009900">"utf-8"</span>);
<span style="color:#880000">// [3]开始写xml文档开头</span>
serializer.startDocument(<span style="color:#009900">"utf-8"</span>, <span style="color:#006666">true</span>);
<span style="color:#880000">// [4]开始写根节点</span>
serializer.startTag(<span style="color:#006666">null</span>, <span style="color:#009900">"smss"</span>);
<span style="color:#880000">// [5]由于短信数据库 系统也通过内容提供者给暴露出来了了 所以我们只需要通过内容解析者去操作数据库</span>
Uri uri = Uri.parse(<span style="color:#009900">"content://sms/"</span>);
Cursor cursor = getContentResolver().query(uri, <span style="color:#000088">new</span> <span style="color:#4f4f4f">String</span>[] { <span style="color:#009900">"address"</span>, <span style="color:#009900">"date"</span>, <span style="color:#009900">"body"</span> }, <span style="color:#006666">null</span>, <span style="color:#006666">null</span>,
<span style="color:#006666">null</span>);
<span style="color:#000088">while</span> (cursor.moveToNext()) {
<span style="color:#4f4f4f">String</span> address = cursor.getString(<span style="color:#006666">0</span>);
<span style="color:#4f4f4f">String</span> date = cursor.getString(<span style="color:#006666">1</span>);
<span style="color:#4f4f4f">String</span> body = cursor.getString(<span style="color:#006666">2</span>);
<span style="color:#880000">// [6]写sms节点</span>
serializer.startTag(<span style="color:#006666">null</span>, <span style="color:#009900">"sms"</span>);
<span style="color:#880000">// [7]写address节点</span>
serializer.startTag(<span style="color:#006666">null</span>, <span style="color:#009900">"address"</span>);
serializer.text(address);
serializer.endTag(<span style="color:#006666">null</span>, <span style="color:#009900">"address"</span>);
<span style="color:#880000">// [8]写body节点</span>
serializer.startTag(<span style="color:#006666">null</span>, <span style="color:#009900">"body"</span>);
serializer.text(body);
serializer.endTag(<span style="color:#006666">null</span>, <span style="color:#009900">"body"</span>);
<span style="color:#880000">// [9]写date节点</span>
serializer.startTag(<span style="color:#006666">null</span>, <span style="color:#009900">"date"</span>);
serializer.text(date);
serializer.endTag(<span style="color:#006666">null</span>, <span style="color:#009900">"date"</span>);
serializer.endTag(<span style="color:#006666">null</span>, <span style="color:#009900">"sms"</span>);
}
serializer.endTag(<span style="color:#006666">null</span>, <span style="color:#009900">"smss"</span>);
serializer.endDocument();
} <span style="color:#000088">catch</span> (Exception e) {
e.printStackTrace();
}
}</code></span>
- 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
- 39
- 40
- 41
- 42
- 43
读取联系人案例:
张萍老师的帖子 - 传智播客论坛_传智播客旗下社区 - Powered by Discuz!(79-83)
主要在微信 QQ,支付宝 等应用多一点
三张主要的表:
1.data 保存联系人的数据
[1].data data1 里面存的是所有联系人的信息
[2].data表里面的raw_contact_id,实际上是raw_contacts表的contact_id
[3].data表里面的mimetype_id列 实际对应mimetypes表
2.raw_contacts表 保存联系人的Id contact_id
3.mimetypes表 保存联系人数据的类型
实际步骤:
1.先读取raw_contact表 读取contact_id字段 从而我就知道实际里面一共有几条联系人
2.再读取data表 根据raw_contact_id去读取data1和mimetype(不是mimetype_id)
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">inquire</span>(View v) {
<span style="color:#880000">// 1.查询raw_contacts表,获取联系人的id</span>
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse(<span style="color:#009900">"content://com.android.contacts/raw_contacts/"</span>);
Uri datauri = Uri.parse(<span style="color:#009900">"content://com.android.contacts/data/"</span>);
Cursor cursor = resolver.query(uri, <span style="color:#000088">new</span> String[] { <span style="color:#009900">"contact_id"</span> }, <span style="color:#000088">null</span>, <span style="color:#000088">null</span>, <span style="color:#000088">null</span>);
<span style="color:#000088">while</span> (cursor.moveToNext()) {
String id = cursor.getString(<span style="color:#006666">0</span>);
<span style="color:#880000">// System.out.println("联系人的id:" + id);</span>
<span style="color:#880000">// 2.根据联系人的id,查询data表,把这个id的数据取出来</span>
<span style="color:#880000">// 系统api 查询data表的时候 不是真正的查询data表 而是查询data表的视图了</span>
<span style="color:#880000">// "mimetype_id"只是视图view_data里面的命名,不是mimetypes表里面的名字</span>
Cursor dataCursor = resolver.query(datauri, <span style="color:#000088">new</span> String[] { <span style="color:#009900">"data1"</span>, <span style="color:#009900">"mimetype"</span> }, <span style="color:#009900">"raw_contact_id=?"</span>,
<span style="color:#000088">new</span> String[] { id }, <span style="color:#000088">null</span>);
<span style="color:#000088">while</span> (dataCursor.moveToNext()) {
String data1 = dataCursor.getString(<span style="color:#006666">0</span>);
<span style="color:#880000">// System.out.println("联系人的data1:" + data1);</span>
String mimetype = dataCursor.getString(<span style="color:#006666">1</span>);
<span style="color:#000088">if</span> (<span style="color:#009900">"vnd.android.cursor.item/name"</span>.equals(mimetype)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"联系人的名字:"</span> + data1);
} <span style="color:#000088">else</span> <span style="color:#000088">if</span> (<span style="color:#009900">"vnd.android.cursor.item/phone_v2"</span>.equals(mimetype)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"联系人的手机号码:"</span> + data1);
} <span style="color:#000088">else</span> <span style="color:#000088">if</span> (<span style="color:#009900">"vnd.android.cursor.item/email_v2"</span>.equals(mimetype)) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"联系人的邮箱:"</span> + data1);
}
}
}
}</code></span>
- 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
PS:在查询的过程中,我们应该查询mimetype这一列,而不是mimetype_id这一列,在查询的时候,我们查询的是view_data视图而不是data表
内容观察者:
84. 内容观察者的原理 - 资源分享 - 传智播客论坛_传智播客旗下社区 - Powered by Discuz!
内容观察者实现的步骤:
1.注册内容观察者(在增删改加入如下的代码可以实现)
<span style="color:#000000"><code>getContext().getContentResolver().notifyChange(uri, <span style="color:#000088">null</span>);<span style="color:#880000">//发送一条消息 说明数据库发生了改变</span></code></span>
- 1
2.定义内容观察者
<span style="color:#000000"><code><span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle savedInstanceState) {
<span style="color:#000088">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<span style="color:#880000">// content://com.test.provider/ uri</span>
<span style="color:#880000">// 第二个参数true代表模糊匹配(content://com.test.provider/),</span>
<span style="color:#880000">// false代表精确匹配(如:content://com.test.provider/query)</span>
Uri uri = Uri.parse(<span style="color:#009900">"content://com.test.provider/"</span>);<span style="color:#880000">//uri在拥有私有数据库的地方注册的authority里面规定</span>
<span style="color:#880000">//Uri uri = Uri.parse("content://com.itheima.provider");</span>
getContentResolver().registerContentObserver(uri, <span style="color:#000088">true</span>, <span style="color:#000088">new</span> MyObserver(<span style="color:#000088">new</span> Handler()));
}
<span style="color:#880000">//定义内容观察者</span>
<span style="color:#000088">private</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyObserver</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">ContentObserver</span> {
<span style="color:#000088">public</span> <span style="color:#009900">MyObserver</span>(Handler handler) {
<span style="color:#000088">super</span>(handler);
<span style="color:#880000">// TODO Auto-generated constructor stub</span>
}
<span style="color:#880000">// 当info表中的数据发生变化时则执行该方法</span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onChange</span>(<span style="color:#000088">boolean</span> selfChange) {
<span style="color:#880000">// TODO Auto-generated method stub</span>
System.out.println(<span style="color:#009900">"数据已经发生改变了~~~~"</span>);
<span style="color:#000088">super</span>.onChange(selfChange);
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
多媒体
PS:Android多媒体指的是:文字、图片、音频、视频
图片:
图片大小的计算公式:图片的总像素 * 每个像素大小
PS:Android中采用的是png格式 Android中采用ARGB Android中一个像素占4byte
缩放需要加载的大图片:
12-03 08:46:01.819: E/AndroidRuntime(3117): Caused by: java.lang.OutOfMemoryError(内存泄漏)
1.获取图片的分辨率
2.获取手机的分辨率 320*480
在onCreate()方法中实现以下方法:
<span style="color:#000000"><code>// <span style="color:#006666">1.</span>获得手机的分辨率,偏向于Java
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE)<span style="color:#880000">;</span>
int winHeight = wm<span style="color:#009900">.getDefaultDisplay</span>()<span style="color:#009900">.getHeight</span>()<span style="color:#880000">;</span>
int winWidth = wm<span style="color:#009900">.getDefaultDisplay</span>()<span style="color:#009900">.getWidth</span>()<span style="color:#880000">;</span>
//<span style="color:#006666">1.1</span>获得手机分辨率的新式写法,偏向于c语言
Point point = new Point()<span style="color:#880000">;</span>
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE)<span style="color:#880000">;</span>
wm<span style="color:#009900">.getDefaultDisplay</span>()<span style="color:#009900">.getSize</span>(point)<span style="color:#880000">;</span>
int Width = point<span style="color:#009900">.x</span><span style="color:#880000">;</span>
int Hight = point<span style="color:#009900">.y</span><span style="color:#880000">;</span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3.计算缩放比
4.按照大的去缩放
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 加载一张大图片</span>
@SuppressLint(<span style="color:#009900">"SdCardPath"</span>)
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click</span>(View v) {
<span style="color:#880000">// 创建一个位图工厂的配置参数</span>
BitmapFactory.Options options = <span style="color:#000088">new</span> Options();
<span style="color:#880000">// 解码器不去真正的解析位图 但是还能够获取图片的宽和高信息</span>
options.inJustDecodeBounds = <span style="color:#000088">true</span>;
BitmapFactory.decodeFile(<span style="color:#009900">"/mnt/sdcard/cc.jpg"</span>, options);
<span style="color:#880000">// [2]获取图片的宽和高信息</span>
<span style="color:#000088">int</span> imgWidth = options.outWidth;
<span style="color:#000088">int</span> imgHeight = options.outHeight;
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"图片的宽和高:"</span> + imgWidth + <span style="color:#009900">"----"</span> + imgHeight);
<span style="color:#880000">// [3]计算缩放缩放比</span>
<span style="color:#000088">int</span> scale = <span style="color:#006666">1</span>;
<span style="color:#000088">int</span> scaleX = imgWidth / width;
<span style="color:#000088">int</span> scaleY = imgHeight / height;
<span style="color:#000088">if</span> (scaleX >= scaleY && scaleX > scale) {
scale = scaleX;
}
<span style="color:#000088">if</span> (scaleY > scaleX && scaleY > scale) {
scale = scaleY;
}
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"缩放比==:"</span> + scale);
<span style="color:#880000">// [4]安装缩放比进行显示 生物学 丁磊</span>
options.inSampleSize = scale;
<span style="color:#880000">// [5]安装缩放比 进行解析位图</span>
options.inJustDecodeBounds = <span style="color:#000088">false</span>;
Bitmap bitmap = BitmapFactory.decodeFile(<span style="color:#009900">"/mnt/sdcard/cc.jpg"</span>, options);
<span style="color:#880000">// [6]把bitmap显示iv上</span>
iv.setImageBitmap(bitmap);
}
</code></span>
- 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
个人理解:先获取图片的像素大小跟手机分辨率进行对比,接着再加载图片
复制图片的原理:
<span style="color:#000000"><code>//显示原图
ImageView iv_src = (ImageView) findViewById(R<span style="color:#009900">.id</span><span style="color:#009900">.iv</span>_src)<span style="color:#880000">; </span>
//显示副本
ImageView iv_copy = (ImageView) findViewById(R<span style="color:#009900">.id</span><span style="color:#009900">.iv</span>_copy)<span style="color:#880000">;</span>
//[<span style="color:#006666">1</span>]先把tomcat<span style="color:#009900">.png</span> 图片转换成bitmap 显示到iv_src
Bitmap srcBitmap = BitmapFactory<span style="color:#009900">.decodeResource</span>(getResources(), R<span style="color:#009900">.drawable</span><span style="color:#009900">.tomcat</span>)<span style="color:#880000">;</span>
//[<span style="color:#006666">1.1</span>]操作图片
//srcBitmap<span style="color:#009900">.setPixel</span>(<span style="color:#006666">20</span>, <span style="color:#006666">30</span>, Color<span style="color:#009900">.RED</span>)<span style="color:#880000">;</span>
iv_src<span style="color:#009900">.setImageBitmap</span>(srcBitmap)<span style="color:#880000">;</span>
//[<span style="color:#006666">2</span>]创建原图的副本
//[<span style="color:#006666">2.1</span>]创建一个模板 相当于 创建了一个大小和原图一样的 空白的白纸
Bitmap copybiBitmap = Bitmap<span style="color:#009900">.createBitmap</span>(srcBitmap<span style="color:#009900">.getWidth</span>(), srcBitmap<span style="color:#009900">.getHeight</span>(), srcBitmap<span style="color:#009900">.getConfig</span>())<span style="color:#880000">;</span>
//[<span style="color:#006666">2.2</span>]想作画需要一个画笔
Paint paint = new Paint()<span style="color:#880000">;</span>
//[<span style="color:#006666">2.3</span>]创建一个画布 把白纸铺到画布上
Canvas canvas = new Canvas(copybiBitmap)<span style="color:#880000">;</span>
//[<span style="color:#006666">2.4</span>]开始作画
canvas<span style="color:#009900">.drawBitmap</span>(srcBitmap, new Matrix(), paint)<span style="color:#880000">;</span>
//[<span style="color:#006666">3</span>]把copybimap显示到iv_copy上
iv_copy<span style="color:#009900">.setImageBitmap</span>(copybiBitmap)<span style="color:#880000">;</span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
图片处理的api:
<span style="color:#000000"><code>Matrix matrix =<span style="color:#009900"> new Matrix();</span></code></span>
- 1
1.对图片进行旋转
<span style="color:#000000"><code>//[<span style="color:#006666">2.5</span>]对图片进行旋转
matrix<span style="color:#009900">.setRotate</span>(<span style="color:#006666">20</span>, srcBitmap<span style="color:#009900">.getWidth</span>()/<span style="color:#006666">2</span>, srcBitmap<span style="color:#009900">.getHeight</span>()/<span style="color:#006666">2</span>)<span style="color:#880000">;</span></code></span>
- 1
- 2
2.对图片进行缩放
<span style="color:#000000"><code><span style="color:#880000">//[2.5]对图片进行缩放</span>
matrix.setScale(<span style="color:#006666">0.5f</span>, <span style="color:#006666">0.5f</span>);</code></span>
- 1
- 2
3.对图片进行平移
<span style="color:#000000"><code><span style="color:#880000">//[2.6]对图片进行平移</span>
<span style="color:#000088">matrix</span>.setTranslate(<span style="color:#006666">30</span>, <span style="color:#006666">0</span>);</code></span>
- 1
- 2
4.镜面(缩放和平移的组合)
<span style="color:#000000"><code><span style="color:#880000">//[2.7]镜面效果 如果2个方法一起用 </span>
<span style="color:#000088">matrix</span>.setScale(-<span style="color:#006666">1.0</span>f, <span style="color:#006666">1</span>);
<span style="color:#880000">//post是在上一次修改的基础上进行再次修改 set 每次操作都是最新的 会覆盖上次的操作</span>
<span style="color:#000088">matrix</span>.postTranslate(srcBitmap.getWidth(), <span style="color:#006666">0</span>);
</code></span>
- 1
- 2
- 3
- 4
- 5
5.倒影()
<span style="color:#000000"><code><span style="color:#880000">//[2,7]倒影效果</span>
<span style="color:#000088">matrix</span>.setScale(<span style="color:#006666">1.0</span>f, -<span style="color:#006666">1</span>);
<span style="color:#880000">//post是在上一次修改的基础上进行再次修改 set 每次操作都是最新的 会覆盖上次的操作</span>
<span style="color:#000088">matrix</span>.postTranslate(<span style="color:#006666">0</span>, srcBitmap.getHeight());
<span style="color:#000088">canvas</span>.drawBitmap(srcBitmap,<span style="color:#000088">matrix</span> , paint);</code></span>
- 1
- 2
- 3
- 4
- 5
音频:
使用mediaplayer播放音频以及视频(只能播放mp4或者3gp格式)
同步:一般播放本地音乐
异步:播放网络音乐 不用开子线程
Surfaceview控件:
SurfaceView 基础用法 - 分享美好的专栏 - 博客频道 - CSDN.NET
1.播放视频
2.重量级控件(在子线程开启好一点),建议可以睡眠几秒
3.它可以直接在子线程更新ui
4.内部的两个线程会相互交换工作:
VideoView控件介绍:
VideoView是对surfaceView和mediaplayer的封装
vitamio框架:
Android视频框架 Vitamio 打造自己的万能播放器 - 郭朝的博客 - 博客频道 - CSDN.NET
解码原理:使用的是一个开源项目 ffmpeg
使用步骤:
1.引入vitamio框架到 Android Studio 或者 Eclipse
2.在布局中定义VideoView
<span style="color:#000000"><code><io<span style="color:#009900">.vov</span><span style="color:#009900">.vitamio</span><span style="color:#009900">.widget</span><span style="color:#009900">.VideoView</span>
android:id=<span style="color:#009900">"@+id/vv"</span>
android:layout_width=<span style="color:#009900">"match_parent"</span>
android:layout_height=<span style="color:#009900">"match_parent"</span> /></code></span>
- 1
- 2
- 3
- 4
3.MainActivity中调用
<span style="color:#000000"><code><span style="color:#880000">// 插件vitamio框架检查是否可用</span>
<span style="color:#000088">if</span> (!LibsChecker.checkVitamioLibs(<span style="color:#000088">this</span>)) {
<span style="color:#000088">return</span>;
}
<span style="color:#000088">final</span> VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath(<span style="color:#009900">"http://192.168.1.20:8080/movie.mp4"</span>); <span style="color:#880000">//设置播放路径</span>
vv.setOnPreparedListener(<span style="color:#000088">new</span> OnPreparedListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onPrepared</span>(MediaPlayer mp) {
vv.start();
}
});
<span style="color:#880000">// 设置video的控制器</span>
vv.setMediaController(<span style="color:#000088">new</span> MediaController(<span style="color:#000088">this</span>));</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
4.使用Vitamio一定要在清单文件额外初始化InitActivity
<span style="color:#000000"><code><span style="color:#880000"><!-- 初始化InitActivity,固定写法 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">activity</span> <span style="color:#4f4f4f">android:name</span>=<span style="color:#009900">"io.vov.vitamio.activity.InitActivity"</span>></span><span style="color:#006666"></<span style="color:#4f4f4f">activity</span>></span></code></span>
- 1
- 2
PS:注意:InitActivity不要和MainActivity混淆。
照相和录像:
<span style="color:#000000"><code>Intent intent = new Intent(MediaStore<span style="color:#009900">.ACTION</span>_IMAGE_CAPTURE)<span style="color:#880000">;//照相</span>
//Intent intent = new Intent(MediaStore<span style="color:#009900">.ACTION</span>_VIDEO_CAPTURE)<span style="color:#880000">;//录像</span>
File file = new File(Environment<span style="color:#009900">.getExternalStorageDirectory</span>()<span style="color:#009900">.getPath</span>(),<span style="color:#009900">"haha.png"</span>)<span style="color:#880000">;</span>
intent<span style="color:#009900">.putExtra</span>(MediaStore<span style="color:#009900">.EXTRA</span>_OUTPUT, Uri<span style="color:#009900">.fromFile</span>(file))<span style="color:#880000">; // 保存图片的位置</span>
// start the image capture Intent
startActivityForResult(intent, <span style="color:#006666">1</span>)<span style="color:#880000">;</span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
Android琐屑知识:
样式和主题:
一般在res文件夹的values文件夹下的styles.xml定义,也可以在values文件夹下新建一个xml来定义
<span style="color:#000000"><code><span style="color:#880000"><!--自定义样式,设置控件宽和高为wrap_content,字体为40sp,字体颜色为纯黑 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">style</span> <span style="color:#4f4f4f">name</span>=<span style="color:#009900">"my_style"</span>></span>
<<span style="color:#000000">item</span> <span style="color:#000000">name</span>="<span style="color:#000000">android</span><span style="color:#000000">:layout_width"</span>><span style="color:#000000">wrap_content</span></<span style="color:#000000">item</span>>
<<span style="color:#000000">item</span> <span style="color:#000000">name</span>="<span style="color:#000000">android</span><span style="color:#000000">:layout_height"</span>><span style="color:#000000">wrap_content</span></<span style="color:#000000">item</span>>
<<span style="color:#000000">item</span> <span style="color:#000000">name</span>="<span style="color:#000000">android</span><span style="color:#000000">:textSize"</span>>40<span style="color:#000000">sp</span></<span style="color:#000000">item</span>>
<<span style="color:#000000">item</span> <span style="color:#000000">name</span>="<span style="color:#000000">android</span><span style="color:#000000">:textColor"</span>><span style="color:#9b703f">#000000</span></<span style="color:#000000">item</span>>
<span style="color:#006666"></<span style="color:#4f4f4f">style</span>></span>
<span style="color:#880000"><!--自定义主题,设置背景颜色为红色 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">style</span> <span style="color:#4f4f4f">name</span>=<span style="color:#009900">"my_theme"</span>></span>
<<span style="color:#000000">item</span> <span style="color:#000000">name</span>="<span style="color:#000000">android</span><span style="color:#000000">:background"</span>><span style="color:#9b703f">#ff0000</span></<span style="color:#000000">item</span>>
<span style="color:#006666"></<span style="color:#4f4f4f">style</span>></span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Andriod国际化
公司俗称”l18n”,其实就是语言的问题,应用需要多种语言
常见对话框
[1]Toast
[2]普通对话框 单选对话框 多选对话框 进度条对话框
普通对话框:
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 弹出一个普通对话框</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click1</span>(View v) {
<span style="color:#880000">// 通过builder 构建器来构造</span>
AlertDialog.Builder builder = <span style="color:#000088">new</span> Builder(<span style="color:#000088">this</span>);
builder.setTitle(<span style="color:#009900">"警告"</span>);
builder.setMessage(<span style="color:#009900">"世界上最遥远的距离是没有网络 "</span>);
builder.setPositiveButton(<span style="color:#009900">"确定"</span>, <span style="color:#000088">new</span> OnClickListener() {
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"点击了确定按钮"</span>);
}
});
builder.setNegativeButton(<span style="color:#009900">"取消"</span>, <span style="color:#000088">new</span> OnClickListener() {
@Override
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
System.<span style="color:#000088">out</span>.println(<span style="color:#009900">"点击了取消按钮 "</span>);
}
});
<span style="color:#880000">// 最后一步 一定要记得 和Toast 一样 show出来</span>
builder.show();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
单选对话框:
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 弹出一个单选对话框</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click2</span>(View v) {
<span style="color:#880000">// 通过builder 构建器来构造</span>
AlertDialog.Builder builder = <span style="color:#000088">new</span> Builder(<span style="color:#000088">this</span>);
builder.setTitle(<span style="color:#009900">"请选择您喜欢的课程"</span>);
<span style="color:#000088">final</span> String items[] = { <span style="color:#009900">"Android"</span>, <span style="color:#009900">"ios"</span>, <span style="color:#009900">"c"</span>, <span style="color:#009900">"C++"</span>, <span style="color:#009900">"html"</span>, <span style="color:#009900">"C#"</span> };
<span style="color:#880000">// -1代表没有条目被选中,0代表默认选中了Android,1代表选中了ios</span>
builder.setSingleChoiceItems(items, -<span style="color:#006666">1</span>, <span style="color:#000088">new</span> OnClickListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
<span style="color:#880000">// [1]把选择的条目给取出来</span>
String item = items[which];
Toast.makeText(getApplicationContext(), item, <span style="color:#006666">1</span>).show();
<span style="color:#880000">// [2]把对话框关闭</span>
dialog.dismiss();
}
});
<span style="color:#880000">// 最后一步 一定要记得 和Toast 一样 show出来</span>
builder.show();
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
复选对话框:
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 弹出一个对选对话框</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click3</span>(View v) {
<span style="color:#880000">// 通过builder 构建器来构造</span>
AlertDialog.Builder builder = <span style="color:#000088">new</span> Builder(<span style="color:#000088">this</span>);
builder.setTitle(<span style="color:#009900">"请选择您喜欢吃的水果"</span>);
<span style="color:#000088">final</span> String items[] = { <span style="color:#009900">"香蕉"</span>, <span style="color:#009900">"黄瓜"</span>, <span style="color:#009900">"哈密瓜"</span>, <span style="color:#009900">"西瓜"</span>, <span style="color:#009900">"梨"</span>, <span style="color:#009900">"柚子"</span>, <span style="color:#009900">"榴莲"</span> };
<span style="color:#000088">final</span> <span style="color:#000088">boolean</span>[] checkedItems = { <span style="color:#000088">true</span>, <span style="color:#000088">false</span>, <span style="color:#000088">false</span>, <span style="color:#000088">false</span>, <span style="color:#000088">false</span>, <span style="color:#000088">false</span>, <span style="color:#000088">true</span> };
builder.setMultiChoiceItems(items, checkedItems, <span style="color:#000088">new</span> OnMultiChoiceClickListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which, <span style="color:#000088">boolean</span> isChecked) {
}
});
builder.setPositiveButton(<span style="color:#009900">"确定"</span>, <span style="color:#000088">new</span> OnClickListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
<span style="color:#880000">// 把选中的 条目的数据给我取出来</span>
StringBuffer sb = <span style="color:#000088">new</span> StringBuffer();
<span style="color:#000088">for</span> (<span style="color:#000088">int</span> i = <span style="color:#006666">0</span>; i < checkedItems.length; i++) {
<span style="color:#880000">// 判断一下 选中的</span>
<span style="color:#000088">if</span> (checkedItems[i]) {
String fruit = items[i];
sb.append(fruit + <span style="color:#009900">" "</span>);
}
}
Toast.makeText(getApplicationContext(), sb.toString(), <span style="color:#006666">1</span>).show();
<span style="color:#880000">// 关闭对话框</span>
dialog.dismiss();
}
});
<span style="color:#880000">// 最后一步 一定要记得 和Toast 一样 show出来</span>
builder.show();
}</code></span>
- 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
进度条对话框:
PS:与进度相关的控件 都可以在子线程更新UI
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 弹出一个进度条对话框</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">click4</span>(View v) {
<span style="color:#000088">final</span> ProgressDialog dialog = <span style="color:#000088">new</span> ProgressDialog(<span style="color:#000088">this</span>);
dialog.setTitle(<span style="color:#009900">"正在玩命加载ing"</span>);
<span style="color:#880000">// 设置一下进度条的样式</span>
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
<span style="color:#880000">// 最后一步一定要记得show 出来</span>
dialog.show();
<span style="color:#880000">// 创建一个子线程</span>
<span style="color:#000088">new</span> Thread() {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
<span style="color:#880000">// 设置进度条最大值</span>
dialog.setMax(<span style="color:#006666">100</span>);
<span style="color:#880000">// 设置当前进度</span>
<span style="color:#000088">for</span> (<span style="color:#000088">int</span> i = <span style="color:#006666">0</span>; i <= <span style="color:#006666">100</span>; i++) {
dialog.setProgress(i);<span style="color:#880000">//显示当前的进度</span>
<span style="color:#880000">// 睡眠一会</span>
SystemClock.sleep(<span style="color:#006666">50</span>);<span style="color:#880000">//谷歌工程师搞出来的</span>
<span style="color:#880000">//Thread.sleep(50);//Java中定义的</span>
}
<span style="color:#880000">// 关闭对话框</span>
dialog.dismiss();
};
}.start();
}</code></span>
- 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
Android中动画:
1.帧动画(Drawable animation ):加载一系列的图片资源
例子详见安卓开发文档
Drawable animation lets you load a series of Drawable resources one after another to create an animation. (帧动画容许你加载图片文件夹中的图片按顺序显示来创建一个动画)
稍微注意一下:
由于AnimationDrawable是在4.0才有的,所以4.0以下的版本认为这个是耗时的操作,所以不会显示动态效果.解决办法:
[1].新开一个子线程
<span style="color:#000000"><code><span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle savedInstanceState) {
<span style="color:#000088">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
<span style="color:#880000">// [1]找到控件 显示动画效果</span>
<span style="color:#000088">final</span> ImageView rocketImage = (ImageView) findViewById(R.id.iv);
<span style="color:#880000">// [2]设置背景资源,加载图片</span>
rocketImage.setBackgroundResource(R.drawable.my_anim);<span style="color:#880000">//my_anim是xml文件名字,所有需要加载的图片资源都应当在这里配置</span>
<span style="color:#880000">// [2.1]兼容低版本的写法</span>
<span style="color:#000088">new</span> Thread() {
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">run</span>() {
<span style="color:#880000">// 这个睡眠是首次启动的时候有效的,可有可无</span>
SystemClock.sleep(<span style="color:#006666">20</span>);
<span style="color:#880000">// [3] 获取AnimationDrawable 类型</span>
AnimationDrawable rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
<span style="color:#880000">// [4]开启动画</span>
rocketAnimation.start();
};
}.start();
}
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
[2].像安卓开发离线文档中的例子来写(轻触一下才可以显示效果)
<span style="color:#000000"><code><span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle savedInstanceState) {
<span style="color:#000088">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView rocketImage = (ImageView) findViewById(R.id.iv);
rocketImage.setBackgroundResource(R.drawable.my_anim);<span style="color:#880000">//my_anim是xml文件名字,所有需要加载的图片资源都应当在这里配置</span>
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
<span style="color:#880000">// 轻触一下才会显示动态效果</span>
<span style="color:#000088">public</span> <span style="color:#000088">boolean</span> <span style="color:#009900">onTouchEvent</span>(MotionEvent event) {
<span style="color:#000088">if</span> (event.getAction() == MotionEvent.ACTION_DOWN) {
rocketAnimation.start();
<span style="color:#000088">return</span> <span style="color:#000088">true</span>;
}
<span style="color:#000088">return</span> <span style="color:#000088">super</span>.onTouchEvent(event);
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.View动画
也叫补间动画
[1]透明 AlphaAnim
[2]旋转 rotateAnim
[3]缩放 scaleAnim
[4]位移 translateAnim
原理:动画效果不会改变控件真实的坐标
<span style="color:#000000"><code><span style="color:#880000">// 点击按钮 实现透明效果</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> click1(View v) {
<span style="color:#880000">//创建透明动画 1.0意味着完全不透明 0.0意外者完全透明 </span>
AlphaAnimation aa = <span style="color:#000088">new</span> AlphaAnimation(<span style="color:#006666">1.0f</span>, <span style="color:#006666">0.0f</span>);
aa.setDuration(<span style="color:#006666">2000</span>); <span style="color:#880000">//设置动画执行的时间</span>
aa.setRepeatCount(<span style="color:#006666">1</span>); <span style="color:#880000">//设置动画重复的次数 </span>
aa.setRepeatMode(Animation.REVERSE); <span style="color:#880000">//设置重复的模式.默认为Animation.RESTART</span>
<span style="color:#880000">//开始执行动画 </span>
iv.startAnimation(aa);
}
<span style="color:#880000">// 点击按钮 实现旋转效果</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> click2(View v) {
<span style="color:#880000">//fromDegrees 开始角度 toDegrees 结束的角度</span>
<span style="color:#880000">// RotateAnimation ra = new RotateAnimation(0, 360);</span>
RotateAnimation ra = <span style="color:#000088">new</span> RotateAnimation(<span style="color:#006666">0</span>, <span style="color:#006666">360</span>, Animation.RELATIVE_TO_SELF, <span style="color:#006666">0.5f</span>, Animation.RELATIVE_TO_SELF, <span style="color:#006666">0.5f</span>);
ra.setDuration(<span style="color:#006666">2000</span>); <span style="color:#880000">//设置动画执行的时间</span>
ra.setRepeatCount(<span style="color:#006666">1</span>); <span style="color:#880000">//设置动画重复的次数 </span>
ra.setRepeatMode(Animation.REVERSE); <span style="color:#880000">//设置重复的模式</span>
<span style="color:#880000">//开始执行动画 </span>
iv.startAnimation(ra);
}
<span style="color:#880000">// 点击按钮 实现缩放效果</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> click3(View v) {
ScaleAnimation sa = <span style="color:#000088">new</span> ScaleAnimation(<span style="color:#006666">1.0f</span>, <span style="color:#006666">2.0f</span>, <span style="color:#006666">1.0f</span>, <span style="color:#006666">2.0f</span>, Animation.RELATIVE_TO_SELF, <span style="color:#006666">0.5f</span>, Animation.RELATIVE_TO_SELF, <span style="color:#006666">0.5f</span>);
sa.setDuration(<span style="color:#006666">2000</span>); <span style="color:#880000">//设置动画执行的时间</span>
sa.setRepeatCount(<span style="color:#006666">1</span>); <span style="color:#880000">//设置动画重复的次数 </span>
sa.setRepeatMode(Animation.REVERSE); <span style="color:#880000">//设置重复的模式</span>
<span style="color:#880000">//开始执行动画 </span>
iv.startAnimation(sa);
}
<span style="color:#880000">// 点击按钮 实现平移效果</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> click4(View v) {
TranslateAnimation ta = <span style="color:#000088">new</span> TranslateAnimation(Animation.RELATIVE_TO_PARENT, <span style="color:#006666">0</span>, Animation.RELATIVE_TO_PARENT, <span style="color:#006666">0</span>, Animation.RELATIVE_TO_PARENT, <span style="color:#006666">0</span>, Animation.RELATIVE_TO_PARENT, <span style="color:#006666">0.2f</span>);
ta.setDuration(<span style="color:#006666">2000</span>); <span style="color:#880000">//设置动画执行的时间</span>
ta.setFillAfter(<span style="color:#000088">true</span>);<span style="color:#880000">//当动画结束后 停留在结束的位置上</span>
<span style="color:#880000">//开始执行动画 </span>
iv.startAnimation(ta);
}</code></span>
- 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
- 39
- 40
- 41
使用xml方式定义补间动画
[1] 就是在res下创建一个目录
[2] 在该目录下创建对应的动画即可
3.属性动画
原理:会改变控件的真实坐标
两种上下文的区别
[1]this 最终继承Context 理解为子类
[2]getApplicationContext() 返回的对象为Context对象 理解为父类
[3]对话框只能用this
选项卡的使用
注意:这种方法已经被废弃,现在使用Fragment居多一点
1.在res/layout增加一个布局.名为activity_base_clear_cache.xml
<span style="color:#000000"><code><span style="color:#006666"><?xml version="1.0" encoding="utf-8"?></span>
<span style="color:#880000"><!-- 放置选项卡和选项卡指向界面的控件 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">TabHost</span> <span style="color:#4f4f4f">xmlns:android</span>=<span style="color:#009900">"http://schemas.android.com/apk/res/android"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:id</span>=<span style="color:#009900">"@android:id/tabhost"</span>></span>
<span style="color:#880000"><!-- 选项卡指向内容页所在的布局 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">FrameLayout</span>
<span style="color:#4f4f4f">android:id</span>=<span style="color:#009900">"@android:id/tabcontent"</span>
<span style="color:#4f4f4f">android:layout_marginBottom</span>=<span style="color:#009900">"50dp"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"match_parent"</span> ></span>
<span style="color:#006666"></<span style="color:#4f4f4f">FrameLayout</span>></span>
<span style="color:#880000"><!-- 选项卡控件 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">TabWidget</span>
<span style="color:#4f4f4f">android:id</span>=<span style="color:#009900">"@android:id/tabs"</span>
<span style="color:#4f4f4f">android:layout_gravity</span>=<span style="color:#009900">"bottom"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"50dp"</span> ></span>
<span style="color:#006666"></<span style="color:#4f4f4f">TabWidget</span>></span>
<span style="color:#006666"></<span style="color:#4f4f4f">TabHost</span>></span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
2.定义一个BaseCacheClearActivity继承TabActivity,接着加载步骤1的xml文件作为布局文件
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">BaseCacheClearActivity</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">TabActivity</span> {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle savedInstanceState) {
<span style="color:#000088">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_clear_cache);
<span style="color:#880000">//1.生成选项卡1</span>
TabSpec tab1 = getTabHost().newTabSpec(<span style="color:#009900">"clear_cache"</span>).setIndicator(<span style="color:#009900">"缓存清理"</span>);<span style="color:#880000">//这里可以加载一个view,也可简单加载字符串</span>
<span style="color:#880000">// ImageView imageView = new ImageView(this); </span>
<span style="color:#880000">// imageView.setBackgroundResource(R.drawable.ic_launcher);</span>
<span style="color:#880000">// View view = View.inflate(this, R.layout.test, null);</span>
<span style="color:#880000">// TabSpec tab1 = getTabHost().newTabSpec("clear_cache").setIndicator(view);</span>
<span style="color:#880000">//2.生成选项卡2</span>
TabSpec tab2 = getTabHost().newTabSpec(<span style="color:#009900">"sd_cache_clear"</span>).setIndicator(<span style="color:#009900">"sd卡清理"</span>);<span style="color:#880000">//这里可以加载一个view,也可简单加载字符串</span>
<span style="color:#880000">//3.告知点中选项卡后续操作</span>
tab1.setContent(<span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>,CacheClearActivity.class));<span style="color:#880000">//CacheClearActivity.class为跳转的界面</span>
tab2.setContent(<span style="color:#000088">new</span> Intent(<span style="color:#000088">this</span>,SDCacheClearActivity.class));<span style="color:#880000">//SDCacheClearActivity.class为跳转的界面</span>
<span style="color:#880000">//4.将此两个选项卡维护host(选项卡宿主)中去</span>
getTabHost().addTab(tab1);
getTabHost().addTab(tab2);
}
}</code></span>
- 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
流量监听
<span style="color:#000000"><code> <span style="color:#880000">//获取手机下载流量</span>
<span style="color:#880000">//获取流量(R 手机(2G,3G,4G)下载流量)</span>
<span style="color:#000088">long</span> mobileRxBytes = TrafficStats.getMobileRxBytes();
<span style="color:#880000">//获取手机的总流量(上传+下载)</span>
<span style="color:#880000">//T total(手机(2G,3G,4G)总流量(上传+下载))</span>
<span style="color:#000088">long</span> mobileTxBytes = TrafficStats.getMobileTxBytes();
<span style="color:#880000">//total(下载流量总和(手机+wifi))</span>
<span style="color:#000088">long</span> totalRxBytes = TrafficStats.getTotalRxBytes();
<span style="color:#880000">//(总流量(手机+wifi),(上传+下载))</span>
<span style="color:#000088">long</span> totalTxBytes = TrafficStats.getTotalTxBytes();
<span style="color:#880000">//以上方法意义不大,一般都是发送短信给运营商查询为准</span>
<span style="color:#880000">//流量获取模块(发送短信),运营商(联通,移动....),(流量监听)第三方接口,广告</span>
<span style="color:#880000">//短信注册</span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
抽屉控件SlidingDrawer 的使用
1.在res/layout的文件夹下定义一个xml布局文件,到时在activity文件加载即可
<span style="color:#000000"><code> <span style="color:#880000"><!-- android:handle="@+id/handler"把手 --></span>
<span style="color:#880000"><!-- android:content="@+id/content"抽屉 --></span>
<span style="color:#880000"><!-- vertical由下往上拖拽 --></span>
<span style="color:#880000"><!-- horizontal水平拖拽 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">SlidingDrawer</span>
<span style="color:#4f4f4f">android:handle</span>=<span style="color:#009900">"@+id/handler"</span>
<span style="color:#4f4f4f">android:content</span>=<span style="color:#009900">"@+id/content"</span>
<span style="color:#4f4f4f">android:orientation</span>=<span style="color:#009900">"vertical"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"match_parent"</span>></span>
<span style="color:#006666"><<span style="color:#4f4f4f">ImageView</span>
<span style="color:#4f4f4f">android:id</span>=<span style="color:#009900">"@id/handler"</span>
<span style="color:#4f4f4f">android:background</span>=<span style="color:#009900">"@drawable/ic_launcher"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"wrap_content"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"wrap_content"</span>/></span>
<span style="color:#880000"><!-- TextView可以修改为其余的一下空间,用于展示不同的抽屉效果 --></span>
<span style="color:#006666"><<span style="color:#4f4f4f">TextView</span>
<span style="color:#4f4f4f">android:id</span>=<span style="color:#009900">"@id/content"</span>
<span style="color:#4f4f4f">android:background</span>=<span style="color:#009900">"#f00"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"match_parent"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"match_parent"</span>/></span>
<span style="color:#006666"></<span style="color:#4f4f4f">SlidingDrawer</span>></span>
</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Application全局捕获异常的使用
1.需要在清单文件的application的标签的name配置一下
2.接着使用一个继承Application来实现
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyApplication</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Application</span> {
<span style="color:#000088">protected</span> <span style="color:#000088">static</span> <span style="color:#000088">final</span> String tag = <span style="color:#009900">"MyApplication"</span>;
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>() {
<span style="color:#000088">super</span>.onCreate();
<span style="color:#880000">//捕获全局(应用任意模块)异常</span>
Thread.setDefaultUncaughtExceptionHandler(<span style="color:#000088">new</span> UncaughtExceptionHandler() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">uncaughtException</span>(Thread thread, Throwable ex) {
<span style="color:#880000">//在获取到了未捕获的异常后,处理的方法</span>
ex.printStackTrace();
Log.i(tag, <span style="color:#009900">"捕获到了一个程序的异常"</span>);
<span style="color:#880000">//将捕获的异常存储到sd卡中</span>
String path = Environment.getExternalStorageDirectory().getAbsoluteFile()+File.separator+<span style="color:#009900">"error74.log"</span>;
File file = <span style="color:#000088">new</span> File(path);
<span style="color:#000088">try</span> {
PrintWriter printWriter = <span style="color:#000088">new</span> PrintWriter(file);
ex.printStackTrace(printWriter);
printWriter.close();
} <span style="color:#000088">catch</span> (FileNotFoundException e) {
e.printStackTrace();
}
<span style="color:#880000">//上传公司的服务器</span>
<span style="color:#880000">//结束应用,发生异常的应用并不会弹出一个恶心的错误对话框</span>
System.exit(<span style="color:#006666">0</span>);
}
});
}
}</code></span>
- 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
Application获得全文的上下文方法
1.需要在清单文件的application的标签的name配置一下
2.继承Application实现其方法:
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">MyApplication</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Application</span> {
<span style="color:#000088">private</span> <span style="color:#000088">static</span> Context mContext;
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>() {
mContext = getApplicationContext();
}
<span style="color:#000088">public</span> <span style="color:#000088">static</span> Context <span style="color:#009900">getContext</span>() {
<span style="color:#000088">return</span> mContext;
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
新特性
Fragments
在实际开发中必须要重写一个方法 onCreateView方法
还可以重写onDestroy方法(有些函数可能需要销毁的时候)
第一种方式(不常用):
[1] 通过onCreateView 这个方法Fragment可以加载自己的布局
[2] name属性指定的是一个我们自己定义的Fragment
[3]直接在布局中声明即可
第二种:
[1]获取Fragment的管理者
<span style="color:#000000"><code>FragmentManager fragmentManager =<span style="color:#009900"> getFragmentManager();//获取Fragment的管理者 通过上下文直接获取</span></code></span>
- 1
[2]开启一个事物
<span style="color:#000000"><code><span style="color:#4f4f4f">FragmentTransaction</span> <span style="color:#000088">begin</span><span style="color:#4f4f4f">Transaction</span> = fragment<span style="color:#4f4f4f">Manager</span>.<span style="color:#000088">begin</span><span style="color:#4f4f4f">Transaction</span>(); //开启事物 </code></span>
- 1
[3]提交事物
<span style="color:#000000"><code>beginTransaction.<span style="color:#000088">commit</span>();//最后一步 记得comment</code></span>
- 1
兼容低版本的写法:就是把所有的Fragment全部使用V4包中的fragment(import导包,v4的fragActivity等)
menu菜单:
[1] 声明菜单
<span style="color:#000000"><code>getMenuInflater()<span style="color:#009900">.inflate</span>(R<span style="color:#009900">.menu</span><span style="color:#009900">.main</span>, menu)<span style="color:#880000">;//菜单item在main.xml那里声明(在menu文件夹下)</span></code></span>
- 1
[2]动态去添加菜单(代码的方式)
<span style="color:#000000"><code><span style="color:#880000">//[2]通过代码的方式添加 </span>
<span style="color:#880000">/**
* menu.add(groupId, itemId, order, title);
* groupId 分组
* itemId 给组件起一个id,方便找到它
* order 排序,数字小的在上面
* title 代表是item的名字
*/</span>
menu.add(<span style="color:#006666">0</span>, <span style="color:#006666">1</span>, <span style="color:#006666">0</span>, <span style="color:#009900">"前进"</span>);
menu.add(<span style="color:#006666">0</span>, <span style="color:#006666">2</span>, <span style="color:#006666">0</span>, <span style="color:#009900">"后退"</span>);
menu.add(<span style="color:#006666">0</span>, <span style="color:#006666">3</span>, <span style="color:#006666">0</span>, <span style="color:#009900">"首页"</span>);</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
menu自定义小技巧:
自定义menu键的时候弹出警告对话框,哪个Activity需要就重写,不重写的Activity是使用系统默认的!!!
<span style="color:#000000"><code><span style="color:#880000">//当菜单打开之前调用这个方法 </span>
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">boolean</span> <span style="color:#009900">onMenuOpened</span>(<span style="color:#000088">int</span> featureId, Menu menu) {
<span style="color:#880000">//弹出 一个对话框 </span>
AlertDialog.Builder builder = <span style="color:#000088">new</span> Builder(<span style="color:#000088">this</span>);
builder.setTitle(<span style="color:#009900">"警告"</span>);
builder.setPositiveButton(<span style="color:#009900">"确定"</span>, <span style="color:#000088">new</span> OnClickListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
}
});
builder.setNegativeButton(<span style="color:#009900">"取消"</span>, <span style="color:#000088">new</span> OnClickListener() {
<span style="color:#9b859d">@Override</span>
<span style="color:#000088">public</span> <span style="color:#000088">void</span> <span style="color:#009900">onClick</span>(DialogInterface dialog, <span style="color:#000088">int</span> which) {
}
});
<span style="color:#880000">//最后一步 记得 show出来 和Toast一样 </span>
builder.show();
<span style="color:#000088">return</span> <span style="color:#000088">false</span>;
}</code></span>
- 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
AutoCompleteTextView控件的介绍:
显示数据的原理跟listview一样 也需要数据适配器(参考官网文档的实例代码即可)
<span style="color:#000000"><code><span style="color:#000088">public</span> <span style="color:#000088">class</span> <span style="color:#4f4f4f">CountriesActivity</span> <span style="color:#000088">extends</span> <span style="color:#4f4f4f">Activity</span> {
<span style="color:#880000">//定义数据</span>
<span style="color:#000088">private</span> String[] COUNTRIES = <span style="color:#000088">new</span> String[] {
<span style="color:#009900">"Belgium"</span>, <span style="color:#009900">"France"</span>, <span style="color:#009900">"Italy"</span>, <span style="color:#009900">"Germany"</span>, <span style="color:#009900">"Spain"</span>
};
<span style="color:#000088">protected</span> <span style="color:#000088">void</span> <span style="color:#009900">onCreate</span>(Bundle icicle) {
<span style="color:#000088">super</span>.onCreate(icicle);
setContentView(R.layout.countries);
<span style="color:#880000">//android.R.layout.simple_dropdown_item_1line其实就是一个系统已经定义好的textview,COUNTRIES是自定义的数组</span>
ArrayAdapter<String> adapter = <span style="color:#000088">new</span> ArrayAdapter<String>(<span style="color:#000088">this</span>,android.R.layout.simple_dropdown_item_1line, COUNTRIES);
<span style="color:#880000">//找到我们需要的组件 </span>
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.countries_list);
<span style="color:#880000">//显示数据</span>
textView.setAdapter(adapter);
}
}</code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
应用程序的反编译:
Android逆向助手
安卓自定义控件
Android自身带的控件不能满足需求, 需要根据自己的需求定义控件.
Src跟Background区别
<span style="color:#000000"><code>
<span style="color:#880000"><!--src代表前景色--></span>
<span style="color:#880000"><!--background 代表背景色,@null代表为透明的意思--></span>
<span style="color:#006666"><<span style="color:#4f4f4f">ImageView
</span> <span style="color:#4f4f4f">android:src</span>=<span style="color:#009900">"#000"</span>
<span style="color:#4f4f4f">android:background</span>=<span style="color:#009900">"@null"</span>
<span style="color:#4f4f4f">android:layout_width</span>=<span style="color:#009900">"wrap_content"</span>
<span style="color:#4f4f4f">android:layout_height</span>=<span style="color:#009900">"wrap_content"</span>/></span></code></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在自定义ViewGroup的时候,如果对子View的测量没有特殊的需求,那么可以继承系统已有的
布局(比如FrameLayout),目的是为了让已有的布局帮我们实行onMeasure;
自定义控件可以分为三大类型
1. 组合已有的控件实现
[1] Button或ImageButton等自带按钮功能的控件会抢夺所在Layout的焦点.导致其他区域点击不生效.在所在layout声明一个属性
<span style="color:#000000"><code>android:descendantFocusability=<span style="color:#009900">"blocksDescendants"</span></code></span>
- 1
blocksDescendants : ViewGroup(父控件)会覆盖子类控件而直接获得焦点
beforeDescendants : ViewGroup(父控件)会优先其子类控件而获取到焦点
afterDescendants : ViewGroup(父控件)只有当其子类控件不需要获取焦点时才获取焦点
[2] popupwindow获取焦点, 外部可点击
<span style="color:#000000"><code><span style="color:#880000">// 设置点击外部区域, 自动隐藏</span>
popupWindow.setOutsideTouchable(<span style="color:#000088">true</span>); <span style="color:#880000">// 外部可触摸</span>
popupWindow.setBackgroundDrawable(<span style="color:#000088">new</span> BitmapDrawable()); <span style="color:#880000">// 设置空的背景, 响应点击事件 </span>
popupWindow.setFocusable(<span style="color:#000088">true</span>); <span style="color:#880000">//设置可获取焦点</span></code></span>
- 1
- 2
- 3
- 4
2. 完全自定义控件.(继承View, ViewGroup)
定义继承view的三个构造方法
<span style="color:#000000"><code><span style="color:#880000">/**
* 自定义开关
*<span style="color:#4f4f4f"> @author</span> poplar
*
* Android 的界面绘制流程
* 测量 摆放 绘制
* measure -> layout -> draw
* | | |
* onMeasure -> onLayout -> onDraw 重写这些方法, 实现自定义控件
*
* onResume()之后执行
*
* View
* onMeasure() (在这个方法里指定自己的宽高) -> onDraw() (绘制自己的内容)
*
* ViewGroup
* onMeasure() (指定自己的宽高, 所有子View的宽高)-> onLayout() (摆放所有子View) -> onDraw() (绘制内容)
*/</span>
<span style="color:#880000">/**
* 用于代码创建控件
*<span style="color:#4f4f4f"> @param</span> context
*/</span>
<span style="color:#000088">public</span> <span style="color:#009900">ToggleView</span>(Context context) {
<span style="color:#000088">super</span>(context);
}
<span style="color:#880000">/**
* 用于在xml里使用, 可指定自定义属性
*<span style="color:#4f4f4f"> @param</span> context
*<span style="color:#4f4f4f"> @param</span> attrs
*/</span>
<span style="color:#000088">public</span> <span style="color:#009900">ToggleView</span>(Context context, AttributeSet attrs) {
<span style="color:#000088">super</span>(context, attrs);
}
<span style="color:#880000">/**
* 用于在xml里使用, 可指定自定义属性, 如果指定了样式, 则走此构造函数
*<span style="color:#4f4f4f"> @param</span> context
*<span style="color:#4f4f4f"> @param</span> attrs
*<span style="color:#4f4f4f"> @param</span> defStyleAttr
*/</span>
<span style="color:#000088">public</span> <span style="color:#009900">ToggleView</span>(Context context, AttributeSet attrs, <span style="color:#000088">int</span> defStyleAttr) {
<span style="color:#000088">super</span>(context, attrs, defStyleAttr);
}</code></span>
- 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
- 39
- 40
- 41
- 42
- 43
一.View移动的相关方法总结:
1.通过改变view在父View的layout位置来移动,但是只能移动指定的View:
view.layout(l,t,r,b);
view.offsetLeftAndRight(offset);//同时改变left和right
view.offsetTopAndBottom(offset);//同时改变top和bottom
2.通过改变scrollX和scrollY来移动,但是可以移动所有的子View;
scrollTo(x,y);
scrollBy(xOffset,yOffset);
3.通过改变Canvas绘制的位置来移动View的内容:
canvas.drawBitmap(bitmap, left, top, paint)
二.使用ViewDragHelper来处理移动
1.ViewDragHelper在高版本的v4包(android4.4以上的v4)中
2.它主要用于处理ViewGroup中对子View的拖拽处理
3.它是Google在2013年开发者大会提出的
4.它主要封装了对View的触摸位置,触摸速度,移动距离等的检测和Scroller,通过接口回调的
方式告诉我们;只需要我们指定是否需要移动,移动多少等;
5.本质是对触摸事件的解析类;
三.getHeight和getMeasuredHeight的区别:
getMeasuredHeight:只要view执行完onMeasure方法就能够获取到值;
getHeight:只有view执行完layout才能获取到值;
安卓开发小Tips:
1.不管你是什么版本的手机,只要进行耗时的操作,比如联网,拷贝大的数据,都默认开多一个线程。获取数据后想要更新UI,那就使用 Handler就可以了。
2.关于xml的数据,是服务器开发人员通过一定的技术手段返回的,对应的Android开发人员我们要解析回就ok,把我们关心的数据取出来,展示Android控件上
3.接口(interface)不可以直接new,但谷歌实现该接口子类都是用base simple default来命名的
4.与进度有关的都可以在子线程更新ui
5.方法上面有这个@Override标志,代表了继承了父类的方法
6.Activity跳转到另外一个Activity,不需要添加flag,但service跳转到Activity的时候,就需要添加flag