天天看点

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

1.Activity初步

1、 一个Activity 就是一个类,并且这个类要继承自 Activity(Android.jar 中的 ) 。

2、 需要override onCreate() 方法。当一个 Activity 第一次运行,显示在手机上的时候,就会调用 onCreate() 方法;由系统调用。

3、 每个Activity 都需要在 AndroidManifest.xml 文件中配置。在 application 标签下的 activity 标签,

[xhtml]  view plain copy

  1. <activity android:name=".Activity01"  
  2.                   android:label="@string/app_name">  
  3.             <intent-filter>  
  4.                 <action android:name="android.intent.action.MAIN" />  
  5.                 <category android:name="android.intent.category.LAUNCHER" />  
  6.             </intent-filter>  
  7. </activity>  

其中:

android:name 属性是 Activity 的名称,以“. ”开头。 android:label 是Activity 的标签名。拥有 intent-filter 子标签的Activity 表明这是程序启动是显示的 Activity 。

1、 为Activity 添加必要的控件。(修改布局文件,一个 Activity 对应一个布局文件,也可以多个 Activity 共同使用一个布局文件)。

2、 一个Activity01 跳转到另外一个 Activity02 ,调用 Activity01 中的 startActivity(Intent intent) 方法,究竟要跳转到哪个 Activity ,跳转后要做什么,都是有 intent 这个对象来决定的。 Intent 非常重要。

3、 Intent中包含的一组信息:

a)  Component name:决定启动哪一个组件( Activity , Services etc. )

b)  Action:跳转到该组件后要做什么动作。

c)  Data: URI ,要传递到下一个组件中的数据( MIME 数据)。

d)  Category

e)  Extras:额外的信息, key-value 通过 intent 来传递。

f)  Flags

新建Activity :新建一个 class ,继承自 Activity 类,实现 o nCreate( Bundle savedInstanceState )方法。然后在 AndroidManifest.xml 中注册。

[xhtml]  view plain copy

  1. <activity android:name=".OtherActivity"   
  2.                   android:label="@string/Other" />  

7、 创建Intent :

[java]  view plain copy

  1. Intent intent = new Intent();  
  2. intent.putExtra("message", "Hello OtherActivity");  
  3. intent.setClass(Activity02.this, OtherActivity.class);  
  4. startActivity(intent);   

putExtra:网 intent 中添加信息( key-value ) ; 获取信息:intent.getStringExtras(String key);

setClass:设置 intent 的起始 activity 和目标 activity ;

startActivity:启动这个 intent 。

2.Activity生命周期

Activity的生命周期

七个生命周期函数

[java]  view plain copy

  1. protected void onCreate(Bundle savedInstanceState);  
  2. protected void onStart();  
  3. protected void onRestart();  
  4. protected void onResume();  
  5. protected void onPause();  
  6. protected void onStop();  
  7. protected void onDestroy();  

启动一个新的Activity 就会依次由 Android 操作系统调用:

onCreate: Activity 第一次被调用;设置布局文件、绑定监听器等操作。

onStart:当 Activity 被显示的时候调用

onResume:当 Activity 能获得用户焦点的时候(即用户可以操作该 activity 的时候)。

当当前运行的Activity 被打断时(来电话或跳到另一个 Activity 时)调用 onPause ,在函数内部编写一些保存当前 Activity 数据的代码。以待返回时还原数据。

当一个Activity 处于不可见状态的时候,就会调用该 Activity 的 onStop 方法。比如跳转到新的 Activity后。如果跳转出来的是一个对话框( Dialog ),则不会调用 onStop 方法。

当一个Activity 调用了 onStop 之后又被返回是,则是调用 onRestart 方法,然后再 onStart 和onResume 。

当明确地调用了一个Activity 的 finish() 方法,或当 Android 系统资源不足,而某个 Activity 处于不可见状态,则系统会选择销毁掉第一个不可见的 Activity ,则系统就会调用这个 Activity 的 onDestroy 方法,销毁这个 Activity 。

一个Activity 在哪些状态下可以被 Android 操作系统 kill 掉?

onPause(仅在 3.0 版本以前 ) , onStop , onDestroy

Task:任务

一个Task 是一个 Activity 的栈( Stack )。在 Activity 之间进行切换,实际就是这个栈的压栈和弹出的过程。

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

示例:两个Activity之间进行切换来观察Activity的生命周期

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

点击Go to Next Activity按钮后:

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程
Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

FirstActivity.java

[java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.content.Intent;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8. public class FirstActivity extends Activity {  
  9.     private Button btn = null;  
  10.     @Override  
  11.     public void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.main);  
  14.         System.out.println("FirstActivity----->OnCreate");  
  15.         btn = (Button) findViewById(R.id.myButton1);  
  16.         btn.setOnClickListener(new GoNextListener());  
  17.     }  
  18.     class GoNextListener implements OnClickListener {  
  19.         @Override  
  20.         public void onClick(View arg0) {  
  21.             Intent intent = new Intent();  
  22.             intent.setClass(FirstActivity.this, SecondActivity.class);  
  23.             startActivity(intent);  
  24.         }  
  25.     }  
  26.     @Override  
  27.     protected void onDestroy() {  
  28.         // TODO Auto-generated method stub  
  29.         System.out.println("FirstActivity----->OnDestroy");  
  30.         super.onDestroy();  
  31.     }  
  32.     @Override  
  33.     protected void onPause() {  
  34.         // TODO Auto-generated method stub  
  35.         System.out.println("FirstActivity----->OnPause");  
  36.         super.onPause();  
  37.     }  
  38.     @Override  
  39.     protected void onRestart() {  
  40.         // TODO Auto-generated method stub  
  41.         System.out.println("FirstActivity----->OnRestart");  
  42.         super.onRestart();  
  43.     }  
  44.     @Override  
  45.     protected void onResume() {  
  46.         // TODO Auto-generated method stub  
  47.         System.out.println("FirstActivity----->OnResume");  
  48.         super.onResume();  
  49.     }  
  50.     @Override  
  51.     protected void onStart() {  
  52.         // TODO Auto-generated method stub  
  53.         System.out.println("FirstActivity----->OnStart");  
  54.         super.onStart();  
  55.     }  
  56.     @Override  
  57.     protected void onStop() {  
  58.         // TODO Auto-generated method stub  
  59.         System.out.println("FirstActivity----->OnStop");  
  60.         super.onStop();  
  61.     }  
  62. }  

SecondActivity.java

[java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. public class SecondActivity extends Activity {  
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         // TODO Auto-generated method stub  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.second);  
  10.         System.out.println("SecondActivity----->OnCreate");  
  11.     }  
  12.     @Override  
  13.     protected void onDestroy() {  
  14.         // TODO Auto-generated method stub  
  15.         System.out.println("SecondActivity----->OnDestroy");  
  16.         super.onDestroy();  
  17.     }  
  18.     @Override  
  19.     protected void onPause() {  
  20.         // TODO Auto-generated method stub  
  21.         System.out.println("SecondActivity----->OnPause");  
  22.         super.onPause();  
  23.     }  
  24.     @Override  
  25.     protected void onRestart() {  
  26.         // TODO Auto-generated method stub  
  27.         System.out.println("SecondActivity----->OnRestart");  
  28.         super.onRestart();  
  29.     }  
  30.     @Override  
  31.     protected void onResume() {  
  32.         // TODO Auto-generated method stub  
  33.         System.out.println("SecondActivity----->OnResume");  
  34.         super.onResume();  
  35.     }  
  36.     @Override  
  37.     protected void onStart() {  
  38.         // TODO Auto-generated method stub  
  39.         System.out.println("SecondActivity----->OnStart");  
  40.         super.onStart();  
  41.     }  
  42.     @Override  
  43.     protected void onStop() {  
  44.         // TODO Auto-generated method stub  
  45.         System.out.println("SecondActivity----->OnStop");  
  46.         super.onStop();  
  47.     }  
  48. }  

Dialog Style Activity的生命周期:

源代码同上述代码一致,只需在AndroidManifest.xml中SecondActivity的声明做如下修改:

[xhtml]  view plain copy

  1. <activity android:name="SecondActivity"   
  2.                   android:label="@string/app_name"  
  3.                   android:theme="@android:style/Theme.Dialog" />  
Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程
Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

在系统中,Activities 被作为一个 activity 栈来管理。当一个新的 activity 启动是,它被压入栈顶并成为运行中的activity ——前一个 activity 将被置于它的下面( 栈中位置 ),并且只要新的activity 存在,旧的 activity 就不会到前台运行。

一个activity 本质上有以下四种状态:

  • 如果一个activity 处于屏幕上前台运行(在栈顶),则称其为 活动 或 运行 状态。
  • 如果一个activity 失去了焦点但还是可见的(也即是,一个新的非全屏显示的或透明的 activity 出现在你的activity 的顶上),它将处于 暂停 状态。一个暂停中的activity 仍然是活着的(它维护着 (activity) 所有的状态和成员信息并且保留着与窗口管理器 (window manager) 的联系),但是当系统处于一个极低的内存状态时可以被杀死。
  • 如果一个activity 被另一个 activity 完全遮盖,则处于 停止 状态。它仍然维护着(activity) 所有的状态和成员信息,但是,它对于用户不再是可见的因此它的窗口被隐藏并且经常因为其他地方需要内存而被系统杀死。
  • 如果一个activity 处于暂停或停止状态,系统可以通过询问是否结束或简单的杀死进程来将其从内存中终止掉。当它重新显示给用户时,它需要完全重新启动然后恢复到之前的状态。

下图显示了一个Activity 的重要状态的路径。方框内表示的是你可以用来当 Activity 在不同状态之间切换是实现一些操作的回调函数。有颜色的椭圆表示 Activity 可以处于的主要一些状态。

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

当监视 activity的状态时,有三个关键的循环是需要注意的:

  • 整个的生命周期( entire lifetime ) 开始与调用onCreate(Bundle) 方法,最后结束与 onDestroy() 方法的调用。 Activity 将在 onCreate() 中完成所有的“全局”设置,然后在 onDestroy() 中释放所占有的全部资源。比如,如果程序有一个从网络上下载数据的后台线程,那就需要在 onCreate() 创建这个线程并在 onDestroy()中停止线程。
  • 一个activity 的 可访问周期( visible lifetime ) 开始于onStart() 的调用,然后一直到一个正确的 onStop() 调用而结束。这期间用户可以在屏幕上看到这个 activity ,尽管它可能不在前面同用户进行交互。在上述两个方法里,你可以维护让 activity 向用户显示所需要的资源。比如,你可以在 onStart() 中注册一个BroadcastReceiver 来监视冲击你的 UI 的变化,而当你所显示的东西不再为用户所看到是在 onStop() 中取消注册。 onStart() 和 onStop() 方法可以随着 activity 对用户的的可访问和隐藏被多次的调用。
  • 一个activity 的 可视周期( foreground lifetime ) 开始于onResume() 的调用,然后一直到一个正确的onPause() 调用而结束。在此期间这个 activity 处于所有 activity 的最前面并同用户进行交互。一个 activity可以频繁地在恢复和暂停状态之间运行——比如当设备进入休眠状态,或当一个 activity 的结果被发送出去,又或一个新的 intent 被发送——所以应尽量减少这些方法里的代码量。

Activity的整个的生命周期被定义成以下的一些方法。所有这些都是你可以用来重写以实现在 activity 的状态改变时完成某些特定工作的 hook(?) 。所有的 activities 都会实现 onCreate(Bundle) 来完成初始化设置;许多也会实现onPause() 来提交数据的变动,要不就是为停止与用户的交互做准备。当实现这些方法时,你应该总是向上从父类中调用。

[java]  view plain copy

  1. public class Activity extends ApplicationContext {  
  2.     protected void onCreate(Bundle savedInstanceState);  
  3.     protected void onStart();  
  4.     protected void onRestart();  
  5.     protected void onResume();  
  6.     protected void onPause();  
  7.     protected void onStop();  
  8.     protected void onDestroy();  
  9. }  

通常来说,一个activity 的生命周期的运转过程是这样的:

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

注意上表中“是否可被杀死”一列——对于这些标记为是的方法,当它返回后,持有这个activity 的进程可能会在未执行其它任何代码的情况下随时被系统杀死。鉴于此,你应该使用 onPause() 方法来将所有的持久化数据(比如用户编辑内容)保存起来。此外, onSaveInstanceState(Bundle) 方法是在将 activity 转为后台 (background) 状态之前调用,以来使你将所有 activity 的动态实例的状态保存到传进来的 Bundle 中,使得这个 activity 要被再度创建时可以在 onCreate(Bundle) 中接收到。可以查阅 Process LifeCycle 部分的内容以了解更多关于进程的生命周期是如何与它所持有的 activity 绑定起来的。注意,将持久化数据在 onPause() 中而非 onSaveInstanceState(Bundle) 中保存,是因为后者不是生命周期的回调函数,所以它不会在其文档中生命的任何情况中调用。

请注意这些语法在HONEYCOMB 版本中发生一些与之前版本不同的细小变化。从 Honeycomb 开始,当 onStop()返回时,程序是不能够被杀死的。这也将影响到 onSaveInstanceState(Bundle) 被调用(它可以在 onPause() 之后被安全地调用,并且允许程序在 onStop() 保存持久化状态之前处于安全的等待状态。

对于那些没有被标记为可杀死的方法,activity 所在的进程不可以在方法被调用、运行和返回之后被杀死。因此一个activity 只有在比如 onPause() 之后和 onResume() 之前处于可被杀死状态。

3.Handler

为什么需要Handler ?

我们不能将所有的操作都放在Activity 中进行。比如:当需要下载一个文件的时候,由于下载时间可能会比较长,而导致 Activity 处于一段较长的时间内无响应状态,用户体验不好,且时间太长的话, Activity 也会报错。

Handler的使用方法:

1、 创建一个Handler 的对象;

2、 当点击某按钮产生事件的时候,调用Handler 的 post() 方法,将要执行的线程的对象添加到队列当中去;

3、 将要执行的操作写在线程对象的run() 方法中;

在run() 方法内部执行 postDelayed() 或者是 post() 方法可以使线程循环执行下去。

实际上Handler 提供了一个异步的线程处理方法。即在 Activity 中将线程 post 到 handler 的队列以后就返回了。这样我们要实现的操作就在新的线程里面运行而不影响到 Activity 的线程。

Android Reference中关于 Handler 的描述:

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.

翻译如下:

    Handler允许你发送和处理消息(Message)和与一个消息队列(MessageQueue)相关联的Runnable对象。每个Handler的对象都与一个单独的线程及这个线程的消息队列相关联。当你创建一个新的Handler时,它将附着于创建它的线程或这个线程的消息队列——从这时开始,它将把消息和Runnable对象传递给消息队列并在它们出队的时候执行它们。

    Handler主要有两个用处:(1)调度消息和Runnable对象在未来某时刻的运行;(2)将一个不在本线程中执行的动作放入队列中。

    消息的调用由post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), 以及sendMessageDelayed(Message, long)方法来完成。post一类的方法允许你将被消息队列调用的Runnable对象放入队列中。sendMessage一类的方法允许你将包含一组将被handleMessage(Message)方法处理的数据的消息对象放入消息队列中(这要求你实现Handler的子类)*即重写Handler的handleMessage(Message)方法。

    当发布(post)或发送(send)对象给Handler,你可以使该对象在消息队列准备好时立即被执行,或者指定一个被处理的时延或被处理的绝对时间。后两者需要实现timeouts、ticks以及其他基于时间的行为。

    当你的程序创建一个进程的时候,它的主线程将被用于运行一个用于处理对顶级(top-level)应用程序对象(如activities、broadcast receivers等)和由它们创建的任意窗口的消息队列。你可以创建自己的线程,并通过Handler与主程序线程进行通讯。这通过你自己线程中的前面所述的post或sendMessage方法来完成。给出的Runnable对象或消息将在Handler的消息队列中调度并在适当时候进行处理。

一个Handler的例子(与ProgressBar结合):点击开始,进度条开始技术

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

源码:

[java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.os.Message;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.ProgressBar;  
  10. public class ProgressBarHandler extends Activity {  
  11.     private ProgressBar bar = null;  
  12.     private Button startButton = null;  
  13.     Handler updateHandler = null;  
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.main);  
  18.         bar = (ProgressBar) findViewById(R.id.myProgress);  
  19.         startButton = (Button) findViewById(R.id.startButton);  
  20.         startButton.setOnClickListener(new ButtonListener());  
  21.     }  
  22.     class ButtonListener implements OnClickListener {  
  23.         @Override  
  24.         public void onClick(View v) {  
  25.             bar.setVisibility(View.VISIBLE);  
  26.             updateBarHandler.post(updateThread); // 将自己创建的线程放入Handler的消息队列中。  
  27.         }  
  28.     }  
  29.     Handler updateBarHandler = new Handler() {  
  30.         @Override  
  31.         public void handleMessage(Message msg) {  
  32.             bar.setProgress(msg.arg1);  
  33.             updateBarHandler.post(updateThread);  
  34.         }  
  35.     };  
  36.     // 创建自己的线程。  
  37.     Thread updateThread = new Thread(new Runnable() {  
  38.         int i = 0;  
  39.         @Override  
  40.         public void run() {  
  41.             System.out.println("Begin Thread");  
  42.             i += 10;  
  43.             // 从Handler的消息池中获取一个消息,并对其成员arg1赋值  
  44.             // 给handlerMessage(Message)使用  
  45.             Message msg = updateBarHandler.obtainMessage();  
  46.             msg.arg1 = i;  
  47.             try {  
  48.                 Thread.sleep(1000);  
  49.             } catch (InterruptedException e) {  
  50.                 e.printStackTrace();  
  51.             }  
  52.             // 将消息放入Handler的消息队列中。  
  53.             updateBarHandler.sendMessage(msg);  
  54.             if (100 == i) {  
  55.                 updateBarHandler.removeCallbacks(updateThread);  
  56.                 bar.setVisibility(View.GONE);  
  57.             }  
  58.         }  
  59.     });  
  60. }  

Handler与线程:

Handler与调用它的 Activity 处于同一线程中。

可以通过在activity 中和 handler 中各自打印线程名称和 id 来验证。

也就是说,通过handler 的 post(Runnable) 方法来执行一个 Runnable ,是直接调用了它的 run() 方法,而不是执行它的 start() 方法。 

因此这种做法并不是我们想要的。

在新线程中处理handler 的方法:

1、创建一个线程来处理,这个线程是专门的,叫做 HandlerThread

[java]  view plain copy

  1. MyHandler myHandler = new MyHandler();  
  2. Message msg = myHandler.obtainMessage();  

2、 创建一个 Handler的子类,要求重载无参构造函数和一个带参数为 Looper 的构造函数,并override handlerMessage(Message) 方法:

[java]  view plain copy

  1. class MyHandler extends Handler {  
  2.         public MyHandler() {  
  3.         }  
  4.         public MyHandler(Looper looper) {  
  5.             super(looper);  
  6.         }  
  7.         @Override  
  8.         public void handleMessage(Message msg) {  
  9.             System.out.println("handler--->" + Thread.currentThread().getId());  
  10.             Bundle bundle = msg.getData();  
  11.             int age = bundle.getInt("age");  
  12.             String name = bundle.getString("name");  
  13.             System.out.println(name + " " + age);  
  14.         }  
  15.     }  

3、 创建一个自定义类的对象,然后从其消息池中获取一个消息对象

[java]  view plain copy

  1. MyHandler myHandler = new MyHandler();  
  2. Message msg = myHandler.obtainMessage();  

4、 对 Message对象进行操作

a)  往Message 中放入简单的整形数据,可以直接给 Message 的成员 int arg1, arg2 赋值

b)  往Message 中放入简单的对象,可以直接给 Message 的成员 Object obj 赋值

c)  往Message 中放入复杂的数据,调用 Message.setData(Bundle) 方法。

*一个 Bundle 可以理解为一个特殊的 Map, 只是这个 Map 的 key 的类型是固定为 String 类型的。Bundle 不仅在消息中传递数据时可以使用,在 intent 中传递数据也可以使用。

5、将Message 对象发送给目标

[java]  view plain copy

  1. // 不同于handler.send(Message),这是Message的方法,将msg发送给目标对象,  
  2. // 所谓目标对象,就是生成该Message的handler对象。  
  3. msg.sendToTarget();  

示例程序完整源代码:

[java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.os.HandlerThread;  
  6. import android.os.Looper;  
  7. import android.os.Message;  
  8. public class HandlerTest2 extends Activity {  
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.main);  
  13.         System.out.println("activity--->" + Thread.currentThread().getId());  
  14.         HandlerThread handlerThread = new HandlerThread("handler_thread");  
  15.         handlerThread.start();  
  16.         MyHandler myHandler = new MyHandler();  
  17.         Message msg = myHandler.obtainMessage();  
  18.         Bundle bundle = new Bundle();  
  19.         bundle.putInt("age", 21);  
  20.         bundle.putString("name", "Bao Yiming");  
  21.         msg.setData(bundle);  
  22.         // 不同于handler.send(Message),这是Message的方法,将msg发送给目标对象,  
  23.         // 所谓目标对象,就是生成该Message的handler对象。  
  24.         msg.sendToTarget();  
  25.     }  
  26.     class MyHandler extends Handler {  
  27.         public MyHandler() {  
  28.         }  
  29.         public MyHandler(Looper looper) {  
  30.             super(looper);  
  31.         }  
  32.         @Override  
  33.         public void handleMessage(Message msg) {  
  34.             System.out.println("handler--->" + Thread.currentThread().getId());  
  35.             Bundle bundle = msg.getData();  
  36.             int age = bundle.getInt("age");  
  37.             String name = bundle.getString("name");  
  38.             System.out.println(name + " " + age);  
  39.         }  
  40.     }  
  41. }  

4.SQLite

一、 SQLiteOpenHelper

这是一个用于数据库的创建和版本管理的工具类。一般创建一个继承自它的子类,并override 它的onCreate(SQLiteDatabase) 和 onUpgrade(SQLiteDatabase, int, int) 方法,来实现自己的操作。也可以override onOpen(SQLiteDatabase) 方法。

这个类将管理一个已经打开的数据库,如果不存在的话则会创建这个数据库,并在必要的时候更新数据库。为了保持数据库在一个敏感(sensible) 的状态,它采用了事务 (transaction) 。

构造方法:

[java]  view plain copy

  1. public SQLiteOpenHelper (  
  2.     Context context,  // 上下文(Activity)  
  3.     String name,  // 数据库文件名,如果数据库已经载入内存,则为null  
  4.     SQLiteDatabase.CursorFactory factory,  // 用来创建指针对象,一般可以写null  
  5.     int version // 数据库的版本,1开始递增的正整数,onUpgrade(SQLiteDatabase,int, int)用来升级版本,onDowngrade(SQLiteDatabase, int, int)   
  6. )  

***如果自定义类继承自SQLiteOpenHelper,则必须override该构造方法!!!

仅仅生成一个SQLiteOpenHelper对象是不会调用onCreate()方法的 , 只有调用了getReadableDatabase()或getWritableDatabase()方法时 , 且是第一次创建数据库,才会调用这个方法。

一、 adb调试工具

命令提示符下输入adb shell 可以进入 android 的 Linux 命令行下。

在/data/data 目录下,存放了应用程序的私有的数据,以创建程序时的 package name 命名

操作sqlite 数据库: sqlite3 <db_name>

进入sqlite 操作环境后,所有的 sqlite 命令都是以“ . ”开头的。

二、 对数据表的插入操作

1、 ContentValues类:用来存储一组数据,具有集合( set )性。类似 Map

2、 创建一个ContentValues 的对象:

[java]  view plain copy

  1. ContentValues content = new ContentValues();  

1、 往 ContentValues中添加数据:

[java]  view plain copy

  1. content.put("id", 1);  
  2. content.put("name", "admin");  

put的时候, key 是对应的表中的字段名。

2、 获取可写数据库,并插入数据

[java]  view plain copy

  1. db = helper.getWritableDatabase();  
  2. db.insert("user", null, content);  

四、 对数据表的更新操作

1、 创建一个 ContentValues对象,并存入要修改的数据:

[java]  view plain copy

  1. ContentValues content = new ContentValues();  
  2. content.put("name", "zhangsan");  

2、 修改数据:

[java]  view plain copy

  1. db.update("user", content, "id=?", new String[]{"1"});  

* 参数说明:

[java]  view plain copy

  1. update(  
  2. String tablename, // 要更新的数据表的名称  
  3. ContentValues content, // 存放数据的ContentValues  
  4. String whereClause, // SQL语句中的where子句的内容  
  5. String[] whereArgs // SQL语句中where子句的参数的值数组  
  6. )  

五、 对数据表的查询操作

1、 查询操作,返回的是一个游标Cursor

2、

[java]  view plain copy

  1. Cursor cursor = db.query("user", new String[]{"id", "name"},   
  2. "id=?", new String[]{"1"}, null, null, null);  

*  参数说明: [java]  view plain copy

  1. public Cursor query (  
  2. String table,  // 要更新的数据表的名称  
  3. String[] columns,  // 要查询的列的数组  
  4. String selection,  // select的条件子句(where 子句)  
  5. String[] selectionArgs, // 条件子句的参数  
  6. String groupBy, // groupBy子句  
  7. String having, // having子句  
  8. String orderBy // orderBy子句  
  9. )  

3、 获取查询到的内容:

Cursor指向查询到的结果集的一个项的上面

使用Cursor.moveNext()

不能以字段名字符串来当参数,只能以列的索引号

[java]  view plain copy

  1. while (cursor.moveToNext()) {  
  2. String name = cursor.getString(cursor.getColumnIndex("name"));  
  3. int id = cursor.getInt(cursor.getColumnIndex("id"));  
  4. System.out.println("id--->" + id);  

5.内存卡操作及文件下载功能的实现

一、权限的获取:

应用程序如要要使用联网功能,或者是操作SD卡,需要在AndroidManifest.xml中配置相应的权限:

[xhtml]  view plain copy

  1. <!-- 联网权限 -->  
  2. <uses-permission android:name="android.permission.INTERNET"/>  
  3. <!-- SD卡操作权限 -->  
  4. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

二、要操作SD卡,首先要读取它在Android操作系统中的路径:

[java]  view plain copy

  1. SDCardPath = Environment.getExternalStorageDirectory() + "/";  

三、获取了SD卡的路径之后的操作,同于Java中的文件IO操作,此不赘述。

四、网络操作

1、由URL获取HTTP连接

[java]  view plain copy

  1. import java.net.HttpURLConnection;  
  2. import java.net.URL;  
  3. url = new URL(strUrl); // 获取URL  
  4. // 获取HTTP连接  
  5. urlConn = (HttpURLConnection) url.openConnection();  

2、由HTTP连接获取输入字节流

[java]  view plain copy

  1. java.io.InputStream = urlConn.getInputStream()  

3、其它操作同Java IO操作

五、示例代码:下载一个文本文件在控制行输出其内容,再下载这个文件保存早SD卡下

1、AndroidManifest.xml

[xhtml]  view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="me.bym"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="4" />  
  7.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  8.         <activity android:name=".DownLoadActivity"  
  9.                   android:label="@string/app_name">  
  10.             <intent-filter>  
  11.                 <action android:name="android.intent.action.MAIN" />  
  12.                 <category android:name="android.intent.category.LAUNCHER" />  
  13.             </intent-filter>  
  14.         </activity>  
  15.     </application>  
  16.     <uses-permission android:name="android.permission.INTERNET"/>  
  17.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
  18. </manifest>  

2、文件操作类FileHelper.java

[java]  view plain copy

  1. package me.bym.utils;  
  2. import java.io.File;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import android.os.Environment;  
  8. public class FileHelper {  
  9.     private String SDCardPath = null; // SD卡在Android文件系统中的路径  
  10.     public String getPath() {  
  11.         return SDCardPath;  
  12.     }  
  13.     public FileHelper() {  
  14.         SDCardPath = Environment.getExternalStorageDirectory() + "/";  
  15.     }  
  16.     public File createSDFile(String fileName) throws IOException {  
  17.         File file = new File(SDCardPath + fileName);  
  18.         file.createNewFile();  
  19.         return file;  
  20.     }  
  21.     public File createSDDir(String dirName) {  
  22.         File dir = new File(SDCardPath + dirName);  
  23.         dir.mkdir();  
  24.         return dir;  
  25.     }  
  26.     public boolean isFileExist(String fileName) {  
  27.         File file = new File(SDCardPath + fileName);  
  28.         return file.exists();  
  29.     }  
  30.     public File writeToSDCard(String path, String fileName,  
  31.             InputStream inputStream) {  
  32.         File file = null;  
  33.         OutputStream output = null;  
  34.         try{  
  35.             createSDDir(path);  
  36.             file = createSDFile(path + fileName);  
  37.             output = new FileOutputStream(file);  
  38.             byte buffer [] = new byte[4 * 1024];  
  39.             while((inputStream.read(buffer)) != -1){  
  40.                 output.write(buffer);  
  41.             }  
  42.             output.flush();  
  43.         }  
  44.         catch(Exception e){  
  45.             e.printStackTrace();  
  46.         }  
  47.         finally{  
  48.             try{  
  49.                 output.close();  
  50.             }  
  51.             catch(Exception e){  
  52.                 e.printStackTrace();  
  53.             }  
  54.         }  
  55.         return file;  
  56.     }  
  57. }  

3、HTTP下载操作类HttpDownloadHelper.java

[java]  view plain copy

  1. package me.bym.utils;  
  2. import java.io.BufferedReader;  
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.URL;  
  9. public class HttpDownloadHelper {  
  10.     private URL url = null;  
  11.     private HttpURLConnection urlConn = null;  
  12.     private final int SUCCESS = 1;  
  13.     private final int EXIST = 0;  
  14.     private final int ERROR = -1;  
  15.     public String textDownload(String strUrl) {  
  16.         StringBuilder sb = new StringBuilder(512); // 初始化文本内容缓冲区。  
  17.         String line = null;  
  18.         BufferedReader br = null;  
  19.         try {  
  20.             url = new URL(strUrl); // 获取URL  
  21.             // 获取HTTP连接  
  22.             urlConn = (HttpURLConnection) url.openConnection();  
  23.             br = new BufferedReader(new InputStreamReader(  
  24.                     urlConn.getInputStream()));  
  25.             while ((line = br.readLine()) != null) {  
  26.                 sb.append(line);  
  27.             }  
  28.         } catch (Exception e) {  
  29.             e.printStackTrace();  
  30.         } finally {  
  31.             try {  
  32.                 br.close();  
  33.             } catch (IOException e) {  
  34.                 e.printStackTrace();  
  35.             }  
  36.         }  
  37.         return sb.toString();  
  38.     }  
  39.     public int fileDownload(String strUrl, String path, String fileName) {  
  40.         FileHelper fileHelper = new FileHelper();  
  41.         InputStream inputStream = null;  
  42.         File file = null;  
  43.         if (fileHelper.isFileExist(path + fileName)) {  
  44.             return EXIST;  
  45.         } else {  
  46.             try {  
  47.                 inputStream = getInputStream(strUrl);  
  48.                 file = fileHelper.writeToSDCard(path, fileName, inputStream);  
  49.                 if (file == null) {  
  50.                     return ERROR;  
  51.                 }  
  52.             } catch (IOException e) {  
  53.                 e.printStackTrace();  
  54.             } finally {  
  55.                 try {  
  56.                     inputStream.close();  
  57.                 } catch (IOException e) {  
  58.                     e.printStackTrace();  
  59.                 }  
  60.             }  
  61.         }  
  62.         return SUCCESS;  
  63.     }  
  64.     private InputStream getInputStream(String strUrl) throws IOException {  
  65.         url = new URL(strUrl);  
  66.         urlConn = (HttpURLConnection) url.openConnection();  
  67.         InputStream is = urlConn.getInputStream();  
  68.         return is;  
  69.     }  
  70. }  

4、Activity类

[java]  view plain copy

  1. package me.bym;  
  2. import me.bym.utils.HttpDownloadHelper;  
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8. public class DownLoadActivity extends Activity {  
  9.     private Button downloadText = null;  
  10.     private Button downloadFile = null;  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main);  
  15.         downloadText = (Button) findViewById(R.id.downloadText);  
  16.         downloadText.setOnClickListener(new downTextListener());  
  17.         downloadFile = (Button) findViewById(R.id.downloadFile);  
  18.         downloadFile.setOnClickListener(new downFileListener());  
  19.     }  
  20.     class downTextListener implements OnClickListener {  
  21.         @Override  
  22.         public void onClick(View v) {  
  23.             HttpDownloadHelper downHelper = new HttpDownloadHelper();  
  24.             String str = downHelper  
  25.                     .textDownload("http://news.swjtu.edu.cn/shownews-2638.html");  
  26.             System.out.println(str);  
  27.         }  
  28.     }  
  29.     class downFileListener implements OnClickListener {  
  30.         @Override  
  31.         public void onClick(View v) {  
  32.             HttpDownloadHelper downHelper = new HttpDownloadHelper();  
  33.             int res = downHelper.fileDownload(  
  34.                     "http://www.swjtu.edu.cn/images/swjtu_title.jpg", "myImg/", "a.html");  
  35.             switch (res) {  
  36.             case 0:  
  37.                 System.out.println("文件已存在");  
  38.                 break;  
  39.             case 1:  
  40.                 System.out.println("文件下载成功");  
  41.                 break;  
  42.             case -1:  
  43.                 System.out.println("文件下载失败");  
  44.                 break;  
  45.             }  
  46.         }  
  47.     }  
  48. }  

6.XML解析

一、 SAX与 DOM 的比较

a)  SAX是 Simple API for XML 的简写,它是一个 XML 解析的标准,也是一组 API (软件包)。它的解析过程是逐行扫描 XML 文档,一种事件驱动模型。它的缺点是对 XML 的读取很方便,解析过程可以随时终止,但是插入、删除等操作很困难。

b)  DOM是 Document Object Model 的简写,它把 XML 文档视为一棵树。解析文档之前,必须先把文档全部载入内存之中。因此效率不高,但可以方便的插入,删除等。

二、 SAX的原理:

对文档进行顺序扫描,当扫描到文档的开始与结束、元素的开始与结束等地方时,通知事件处理函数,由事件处理函数作出相应动作,然后继续同样的扫描,直到文档结束。

大多数SAX 实现都会产生以下类型的事件:

1、 在文档的开始和结束时触发文档处理事件;

2、 在文档内每一个XML 元素接受解析的前后触发元素事件;

3、 任何元数据通常都由单独的事件交付;

4、 任何处理文档的DTD 或 schema 时产生的 DTD 或 schema 事件;

5、 产生错误事件用来通知主机应用程序解析错误。

三、 SAX模型

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

三、 SAX的解析过程

对于如下文档

<doc><para>Hello, world!</para></doc>

解析过程中会产生如下一系列事件:

start document

start element: doc

start element: para

characters: Hello, world!

end element: para

end element: doc

end document 

1、创建事件处理器

2、 创建SAX 解析器

3、 将事件处理程序分配给解析器

4、 对文档进行解析,将每个事件分配给处理程序。

四、 SAX的常用接口

a)  org.xml.sax.ContentHandler 接口:封装了一些对事件处理的方法:

i.  void startDocument()

ii.  void endDocument()

iii.  startElement(

String uri, // 命名空间的 URI

String localName, // 标签的名字,不包含前缀

String qName,  // 标签的名字,包含前缀

Attributes atts // 标签的所有属性

)

iv.  endElement(

String uri, 

String localName, 

String qName)

v.  void characters(

char[] ch,  // 要解析的字符串

int start,  // 开始位置

int length // 长度

)

六、 对元素属性的操作:

在startElement 方法中:

[java]  view plain copy

  1. for (int i = 0; i < attributes.getLength(); ++i) {  
  2.         System.out.println(attributes.getLocalName(i) + "="  
  3.                         + attributes.getValue(i));  
  4.             }  

示例程序,对以下XML文件的解析

[xhtml]  view plain copy

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <workers>  
  3.     <worker id="AQ01">  
  4.         <name>Mark</name>  
  5.         <sex>Male</sex>  
  6.         <position>Manager</position>  
  7.         <city>Beijing</city>  
  8.         <salary>4000</salary>  
  9.     </worker>  
  10.     <worker id="AD02">  
  11.         <name>Lucy</name>  
  12.         <sex>Female</sex>  
  13.         <position>Staff</position>  
  14.         <city>Shanghai</city>  
  15.         <salary>1000</salary>  
  16.     </worker>  
  17.     <worker id="AD03">  
  18.         <name>Lily</name>  
  19.         <sex>Female</sex>  
  20.         <position>Staff</position>  
  21.         <city>Beijing</city>  
  22.         <salary>3000</salary>  
  23.     </worker>  
  24. </workers>  

MyContentHandler.java

[java]  view plain copy

  1. package me.bym;  
  2. import org.xml.sax.Attributes;  
  3. import org.xml.sax.SAXException;  
  4. import org.xml.sax.helpers.DefaultHandler;  
  5. public class MyContentHandler extends DefaultHandler {  
  6.     String name = null;  
  7.     String city = null;  
  8.     String salary = null;  
  9.     String sex = null;  
  10.     String position = null;  
  11.     String tagName = null;  
  12.     @Override  
  13.     public void characters(char[] ch, int start, int length)  
  14.             throws SAXException {  
  15.         if (tagName.equals(name)) {  
  16.             name = new String(ch, start, length);  
  17.         } else if (tagName.equals("sex")) {  
  18.             sex = new String(ch, start, length);  
  19.         } else if (tagName.equals("position")) {  
  20.             position = new String(ch, start, length);  
  21.         } else if (tagName.equals(salary)) {  
  22.             salary = new String(ch, start, length);  
  23.         } else if (tagName.equals(city)) {  
  24.             city = new String(ch, start, length);  
  25.         }  
  26.     }  
  27.     @Override  
  28.     public void endDocument() throws SAXException {  
  29.         System.out.println("=====End=====");  
  30.     }  
  31.     @Override  
  32.     public void endElement(String uri, String localName, String qName)  
  33.             throws SAXException {  
  34.         tagName = "";  
  35.         if (localName.equals("worker")) {  
  36.             System.out.println("name: " + name);  
  37.             System.out.println("sex: " + sex);  
  38.             System.out.println("position: " + position);  
  39.             System.out.println("salary: " + salary);  
  40.             System.out.println("city: " + city);  
  41.         }  
  42.     }  
  43.     @Override  
  44.     public void startDocument() throws SAXException {  
  45.         System.out.println("=====Begin=====");  
  46.     }  
  47.     @Override  
  48.     public void startElement(String uri, String localName, String qName,  
  49.             Attributes attributes) throws SAXException {  
  50.         tagName = localName;  
  51.         if (localName.equals("worker")) {  
  52.             for (int i = 0; i < attributes.getLength(); ++i) {  
  53.                 System.out.println(attributes.getLocalName(i) + "="  
  54.                         + attributes.getValue(i));  
  55.             }  
  56.         }  
  57.     }  
  58. }  

Activity

[java]  view plain copy

  1. package me.bym;  
  2. import java.io.IOException;  
  3. import java.io.StringReader;  
  4. import javax.xml.parsers.ParserConfigurationException;  
  5. import javax.xml.parsers.SAXParserFactory;  
  6. import org.xml.sax.InputSource;  
  7. import org.xml.sax.SAXException;  
  8. import org.xml.sax.XMLReader;  
  9. import android.app.Activity;  
  10. import android.os.Bundle;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. public class XMLParse extends Activity {  
  15.     private Button parseButton = null;  
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.         parseButton = (Button) findViewById(R.id.parseButton);  
  21.         parseButton.setOnClickListener(new parseListener());  
  22.     }  
  23.     class parseListener implements OnClickListener {  
  24.         @Override  
  25.         public void onClick(View v) {  
  26.             String xml = "";  
  27.             try {  
  28.                 // 创建一个SAXParserFactory  
  29.                 SAXParserFactory factory = SAXParserFactory.newInstance();  
  30.                 XMLReader reader = factory.newSAXParser().getXMLReader();  
  31.                 // 为XMLReader设置内容处理器  
  32.                 reader.setContentHandler(new MyContentHandler());  
  33.                 // 开始解析文件  
  34.                 reader.parse(new InputSource(new StringReader(xml)));  
  35.             } catch (SAXException e) {  
  36.                 e.printStackTrace();  
  37.             } catch (ParserConfigurationException e) {  
  38.                 e.printStackTrace();  
  39.             } catch (IOException e) {  
  40.                 e.printStackTrace();  
  41.             }  
  42.         }  
  43.     }  
  44. }  

7.Broadcast 机制

一、 Android广播机制

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

二、 在AndroidManifest.xml 中的配置

[xhtml]  view plain copy

  1. <receiver android:name=".TestRecevier">  
  2.     <intent-filter>  
  3.         <action android:name="android.intent.action.EDIT" />  
  4.     </intent-filter>  
  5. </receiver>  

表示要启动这个broadcast recevier ,需要给它发送一个 intent ,里面 <intent-filter> 标签表示发送给它的 intent需要满足一定的条件才能被接受。

一、 一个Recevier 接收到广播时会创建一个对象,当接收完毕做完相应的处理之后这个对象就被废弃成为垃圾对象了(从 onRecevie() 方法返回了,系统就认为其不再是活动状态),以后再次发送广播,将要重新生成对象。

二、 又见Intent

Intent提供了代码在不同程序中的迟运行时绑定 (late runtime binding) ,最主要的用处在于启动 activities 。一个动作 (action) 的启动被抽象出两个数据结构:

1、 action

2、 data

即对数据进行什么操作。

1、标准的 Activity Actions

·  ACTION_MAIN

·  ACTION_VIEW

·  ACTION_ATTACH_DATA

·  ACTION_EDIT

·  ACTION_PICK

·  ACTION_CHOOSER

·  ACTION_GET_CONTENT

·  ACTION_DIAL

·  ACTION_CALL

·  ACTION_SEND

·  ACTION_SENDTO

·  ACTION_ANSWER

·  ACTION_INSERT

·  ACTION_DELETE

·  ACTION_RUN

·  ACTION_SYNC

·  ACTION_PICK_ACTIVITY

·  ACTION_SEARCH

·  ACTION_WEB_SEARCH

·  ACTION_FACTORY_TEST

2、标准的广播 Actions ,通过 registerReceiver(BroadcastReceiver, IntentFilter) 或在 AndroidManifest.xml中用<receiver> 标签注册)

·  ACTION_TIME_TICK

·  ACTION_TIME_CHANGED

·  ACTION_TIMEZONE_CHANGED

·  ACTION_BOOT_COMPLETED

·  ACTION_PACKAGE_ADDED

·  ACTION_PACKAGE_CHANGED

·  ACTION_PACKAGE_REMOVED

·  ACTION_PACKAGE_RESTARTED

·  ACTION_PACKAGE_DATA_CLEARED

·  ACTION_UID_REMOVED

·  ACTION_BATTERY_CHANGED

·  ACTION_POWER_CONNECTED

·  ACTION_POWER_DISCONNECTED

·  ACTION_SHUTDOWN

五、 Broadcast的机制详解:

在activity 中:

[java]  view plain copy

  1. Intent intent = new Intent();  
  2. intent.setAction(Intent.ACTION_EDIT);  
  3. TestActivity.this.sendBroadcast(intent);  

对intent 设置了 action ,然后通过 sendBroadcast(intent) 将这个 intent 广播出去,然后在 AndroidMenifest 中注册了相应 action 的 BroadcastRecevier 就能接受这个广播消息并作出处理。

五、 注册Broadcast Receiver 的方法

BroadcastReceiver用于监听被广播的事件( Intent ),为了达到这个目的, BroadcastRecevier 必须先进行注册,注册的方法有两种:

1、 在AndroidManifest.xml 当中进行注册

[xhtml]  view plain copy

  1. <receiver android:name=".TestReceiver">  
  2.     <intent-filter>  
  3.         <action android:name="android.intent.action.EDIT" />  
  4.     </intent-filter>  
  5. </receiver>  

说明:在AndroidManifest.xml 中注册 receiver 的话,即使这个应用程序被关闭掉, receiver 仍然可以接受广播消息。

2、 在应用程序的代码当中进行注册

注册BroadcastReceiver —— registerReceiver(receiver, filter) filter 对应的是在 AndroidManifest.xml 中注册时的intent-filter 。

取消注册BroadcastReceiver —— unregisterReceiver(receiver)

如果一个BroadcastReceiver 用于更新 UI ,通常会使用这种方法来进行注册,通常在 Activity 启动的时候进行注册,在 Activity 不可见的时候取消注册。

[java]  view plain copy

  1. smsReceiver = new SMSReceiver(); // 生成一个BroadcastReceiver对象  
  2. IntentFilter filter = new IntentFilter(); // 生成一个IntentFilter对象  
  3. filter.addAction(SMS_ACTION); // 为IntentFilter对象添加一个Action  
  4. TestBC2.this.registerReceiver(smsReceiver, filter);//注册这个Receiver  
  5. System.out.println("注册监听器成功");  

七、 短信的操作:

[java]  view plain copy

  1. // 接受Intent对象当中的数据  
  2. Bundle bundle = intent.getExtras();  
  3. // 在Bundle当中有一个属性名为pdus,这个属性的值是一个Object数组  
  4. Object[] myOBJpdus = (Object[]) bundle.get("pdus");  
  5. // 创建一个SmsMessage类型的数组  
  6. SmsMessage[] messages = new SmsMessage[myOBJpdus.length];  
  7. System.out.println(messages.length);  
  8. for (int i = 0; i < myOBJpdus.length; ++i) {  
  9. // 使用Object数组当中的对象来创建SmsMessage对象  
  10. messages[i] = SmsMessage.createFromPdu((byte[]) myOBJpdus[i]);  
  11. //调用SmsMessage对象的getDisppalyMessageBody()方法,就可以得到消息的内容  
  12. System.out.println(messages[i].getDisplayMessageBody());  

示例代码:监听手机短信 1、AndroidManifest.xml

[xhtml]  view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="me.bym"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="4" />  
  7.     <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>  
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  9.         <activity android:name=".TestBC2"  
  10.                   android:label="@string/app_name">  
  11.             <intent-filter>  
  12.                 <action android:name="android.intent.action.MAIN" />  
  13.                 <category android:name="android.intent.category.LAUNCHER" />  
  14.             </intent-filter>  
  15.         </activity>  
  16.     </application>  
  17. </manifest>  

2、Activity [java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.content.IntentFilter;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8. public class TestBC2 extends Activity {  
  9.     private Button registerButton = null;  
  10.     private Button unregisterButton = null;  
  11.     private SMSReceiver smsReceiver = null;  
  12.     private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         registerButton = (Button) findViewById(R.id.registerButton);  
  18.         unregisterButton = (Button) findViewById(R.id.unregisterButton);  
  19.         registerButton.setOnClickListener(new RegisterReceiverListener());  
  20.         unregisterButton.setOnClickListener(new UnRegisterReceiverListener());  
  21.     }  
  22.     class RegisterReceiverListener implements OnClickListener {  
  23.         @Override  
  24.         public void onClick(View v) {  
  25.             smsReceiver = new SMSReceiver(); // 生成一个BroadcastReceiver对象  
  26.             IntentFilter filter = new IntentFilter(); // 生成一个IntentFilter对象  
  27.             filter.addAction(SMS_ACTION); // 为IntentFilter对象添加一个Action  
  28.             TestBC2.this.registerReceiver(smsReceiver, filter); // 注册这个Receiver  
  29.             System.out.println("注册监听器成功");  
  30.         }  
  31.     }  
  32.     class UnRegisterReceiverListener implements OnClickListener {  
  33.         @Override  
  34.         public void onClick(View v) {  
  35.             if (smsReceiver != null) {  
  36.                 TestBC2.this.unregisterReceiver(smsReceiver);  
  37.                 System.out.println("解除监听器注册成功");  
  38.             }  
  39.         }  
  40.     }  
  41. }  

3、Broadcast Receiver [java]  view plain copy

  1. package me.bym;  
  2. import android.content.BroadcastReceiver;  
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.telephony.SmsMessage;  
  7. public class SMSReceiver extends BroadcastReceiver {  
  8.     @Override  
  9.     public void onReceive(Context context, Intent intent) {  
  10.         System.out.println("receiver message");  
  11.         // 接受Intent对象当中的数据  
  12.         Bundle bundle = intent.getExtras();  
  13.         // 在Bundle当中有一个属性名为pdus,这个属性的值是一个Object数组  
  14.         Object[] myOBJpdus = (Object[]) bundle.get("pdus");  
  15.         // 创建一个SmsMessage类型的数组  
  16.         SmsMessage[] messages = new SmsMessage[myOBJpdus.length];  
  17.         System.out.println(messages.length);  
  18.         for (int i = 0; i < myOBJpdus.length; ++i) {  
  19.             // 使用Object数组当中的对象来创建SmsMessage对象  
  20.             messages[i] = SmsMessage.createFromPdu((byte[]) myOBJpdus[i]);  
  21.             //调用SmsMessage对象的getDisppalyMessageBody()方法,就可以得到消息的内容  
  22.             System.out.println(messages[i].getDisplayMessageBody());  
  23.         }  
  24.     }  
  25. }  

8.Wifi操作

1、 WIFI网卡的状态

WIFI网卡的状态信息都以整型变量的形式存放在 android.net.wifi.WifiManager 类中,有以下状态:

WIFI_STATE_DISABLED WIFI网卡不可用
WIFI_STATE_DISABLING WIFI网卡正在关闭
WIFI_STATE_ENABLED WIFI网卡可用
WIFI_STATE_ENABLING WIFI网卡正在打开
WIFI_STATE_UNKNOWN WIFI网卡状态未知

2、 操作WIFI 网卡所需的权限

CHANGE_NETWORK_STATE 允许应用程序改变网络连接状态
CHANGE_WIFI_STATE 允许应用程序改变WIFI 连接状态
ACCESS_NETWORK_STATE 允许应用程序获取网络的状态信息
ACCESS_WIFI_STATE 允许应用程序获得WIFI 的状态信息

3、 改变WIFI 网卡的状态

对WIFI 网卡进行操作需要通过对 WifiManager 对象来进行,获取该对象的方法如下:

[java]  view plain copy

  1. WifiManager wifiManager=(WifiManager) Context.getSystemService(Service.WIFI_SERVICE);  

打开WIFI 网卡:

[java]  view plain copy

  1. wifiManager.setWifiEnabled(true);  

关闭WIFI 网卡

[java]  view plain copy

  1. wifiManager.setWifiEnabled(false);  

获取网卡的当前状态:

[java]  view plain copy

  1. wifiManager.getWifiState();  

示例代码:由于Android模拟器不支持wifi操作,所以例子需要在实体手机上运行

AndroidManifest.xml

[xhtml]  view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="me.bym" android:versionCode="1" android:versionName="1.0">  
  4.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  5.         <activity android:name=".WifiActivity" android:label="@string/app_name">  
  6.             <intent-filter>  
  7.                 <action android:name="android.intent.action.MAIN" />  
  8.                 <category android:name="android.intent.category.LAUNCHER" />  
  9.             </intent-filter>  
  10.         </activity>  
  11.     </application>  
  12.     <uses-sdk android:minSdkVersion="4" />  
  13.     <!-- 以下是使用wifi访问网络所需要的权限 -->  
  14.     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>  
  15.     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>  
  16.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>  
  17.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>  
  18. </manifest>   

Activity

[java]  view plain copy

  1. package me.bym;  
  2. import android.app.Activity;  
  3. import android.content.Context;  
  4. import android.net.wifi.WifiManager;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. import android.widget.Toast;  
  10. public class WifiActivity extends Activity {  
  11.     private Button startWifiButton = null;  
  12.     private Button shutdownWifiButton = null;  
  13.     private Button checkStateButton = null;  
  14.     private WifiManager wifiManager = null;  
  15.     private String res = ""; // 用来存放操作结果信息的字符串  
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.         startWifiButton = (Button) findViewById(R.id.StartWifiButton);  
  21.         shutdownWifiButton = (Button) findViewById(R.id.ShutdownWifiButton);  
  22.         checkStateButton = (Button) findViewById(R.id.CheckStateButton);  
  23.         startWifiButton.setOnClickListener(new StartWifiListener());  
  24.         shutdownWifiButton.setOnClickListener(new ShutdownWifiListener());  
  25.         checkStateButton.setOnClickListener(new CheckStateListener());  
  26.     }  
  27.     class StartWifiListener implements OnClickListener {  
  28.         @Override  
  29.         public void onClick(View v) {  
  30.             wifiManager = (WifiManager) WifiActivity.this  
  31.                     .getSystemService(Context.WIFI_SERVICE);  
  32.             if (wifiManager.setWifiEnabled(true)) {  
  33.                 res = "启动wifi服务成功";  
  34.             } else {  
  35.                 res = "启动wifi服务失败";  
  36.             }  
  37.             Toast.makeText(WifiActivity.this, res, Toast.LENGTH_SHORT).show();  
  38.         }  
  39.     }  
  40.     class ShutdownWifiListener implements OnClickListener {  
  41.         @Override  
  42.         public void onClick(View v) {  
  43.             wifiManager = (WifiManager) WifiActivity.this  
  44.                     .getSystemService(Context.WIFI_SERVICE);  
  45.             if (wifiManager.setWifiEnabled(false)) {  
  46.                 res = "关闭wifi服务成功";  
  47.             } else {  
  48.                 res = "关闭wifi服务失败";  
  49.             }  
  50.             Toast.makeText(WifiActivity.this, res, Toast.LENGTH_SHORT).show();  
  51.         }  
  52.     }  
  53.     class CheckStateListener implements OnClickListener {  
  54.         @Override  
  55.         public void onClick(View v) {  
  56.             wifiManager = (WifiManager) WifiActivity.this  
  57.                     .getSystemService(Context.WIFI_SERVICE);  
  58.             switch (wifiManager.getWifiState()) {  
  59.             case WifiManager.WIFI_STATE_DISABLED:  
  60.                 res = "WIFI已关闭";  
  61.                 break;  
  62.             case WifiManager.WIFI_STATE_DISABLING:  
  63.                 res = "WIFI正在关闭中";  
  64.                 break;  
  65.             case WifiManager.WIFI_STATE_ENABLED:  
  66.                 res = "WIFI已启用";  
  67.                 break;  
  68.             case WifiManager.WIFI_STATE_ENABLING:  
  69.                 res = "WIFI正在启动中";  
  70.                 break;  
  71.             case WifiManager.WIFI_STATE_UNKNOWN:  
  72.                 res = "未知WIFI状态";  
  73.                 break;  
  74.             }  
  75.             Toast.makeText(WifiActivity.this, res, Toast.LENGTH_SHORT).show();  
  76.         }  
  77.     }  
  78. }  
Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

9.TCP/IP socket编程

先来介绍下网络协议:  

    TCP/IP  

        Transmission Control Protocol 传输控制协议  

        Internet Protocol 互联网协议  

    UDP  

        User Datagram Protocol 用户数据协议  

连接协议:  

    分为:  

    面向连接协议: Connection Oriented Protocol  

    非连接协议: Connectionless Protocol  

    1).面向连接协议是指两台电脑在传输数据前,先会建立一个专属的连接。就如电信局的交换机会为打电话双方提供专属连接一样。  

    Internet上的面向连接协议就是 TCP/IP  

    特点:确认回应;分组序号;流量控制。  

    TCP/IP属于可靠性传输,适合不容许有传输错误的网络程序设计使用  

    2).非连接协议:无专属连接,无分组,容错,距离短,可同时对多台电脑进行数据传输  

    Internet上的非连接协议就是 UDP  

    TCP在网络通信上有极强的生命力,例如远程连接( Telnet )和文件传输( FTP )都需要不定长度的数据被可靠地传输。相比之下 UDP 操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server 应用程序。  

Socket 是程序与网络间的一种接口,大部分网络应用程序都是点对点的,所谓点就是服务器端和客户端所执行的程序。 Socket 是用来接收和传送分组的一个端点。  

java的 Socket 编程要用到 java.net 包,最常用的是 net 包下的 6 个类: InetAddress( 互联网协议  (IP)  地址 ) 类,Socket( 套接字 ) 类, ServerSocket( 套接字服务器 ) 类, DatagramSocket( 发送和接收数据报包的套接字 )  类,DatagramPacket( 数据报包 ) 类, MulticastSocket( 多播数据报套接字类用于发送和接收  IP  多播包 ) 类,其中InetAddress 、 Socket 、 ServerSocket 类是属于 TCP 面向连接协议, DatagramSocket 、  DatagramPacket 和MulticastSocket 类则属于 UDP 非连接协议的传送类。 

——From: http://cuishen.iteye.com/blog/242842

TCP 通信模型

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

Socket模型

Android笔记总结1.Activity初步2.Activity生命周期3.Handler4.SQLite5.内存卡操作及文件下载功能的实现6.XML解析7.Broadcast 机制 8.Wifi操作9.TCP/IP socket编程

示例代码:

UdpServer.java

[java]  view plain copy

  1. package me.bym.udp;  
  2. import java.io.IOException;  
  3. import java.net.DatagramPacket;  
  4. import java.net.DatagramSocket;  
  5. import java.net.SocketException;  
  6. public class UdpServer {  
  7.     public static void main(String[] args) {  
  8.         // 声明UPD socket,即DatagramSocket  
  9.         DatagramSocket socket = null;  
  10.         try {  
  11.             // 产生DatagramSocket对象,制定监听端口  
  12.             socket = new DatagramSocket(1234);  
  13.             // 设置消息读取缓冲区  
  14.             byte data[] = new byte[512];  
  15.             // 声明和定义UDP数据包,内容是消息缓冲区的内容  
  16.             DatagramPacket packet = new DatagramPacket(data, data.length);  
  17.             // 调用阻塞方法receiver接受客户端发来的内容存放到消息缓冲区packet中  
  18.             socket.receive(packet);  
  19.             // 打印消息  
  20.             String msg = new String(packet.getData(), packet.getOffset(),  
  21.                     packet.getLength());  
  22.             System.out.println(msg);  
  23.         } catch (SocketException e) {  
  24.             // TODO Auto-generated catch block  
  25.             e.printStackTrace();  
  26.         } catch (IOException e) {  
  27.             // TODO Auto-generated catch block  
  28.             e.printStackTrace();  
  29.         } finally {  
  30.             // 关闭socket  
  31.             socket.close();  
  32.         }  
  33.     }  
  34. }  

UdpClient.java

[java]  view plain copy

  1. package me.bym.udp;  
  2. import java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.net.DatagramPacket;  
  6. import java.net.DatagramSocket;  
  7. import java.net.InetAddress;  
  8. import java.net.SocketException;  
  9. public class UdpClient {  
  10.     public static void main(String[] args) {  
  11.         DatagramSocket socket = null;  
  12.         String msg = null;  
  13.         try {  
  14.             socket = new DatagramSocket();  
  15.             // 从标准输入(键盘)读取数据  
  16.             BufferedReader reader = new BufferedReader(new InputStreamReader(  
  17.                     System.in));  
  18.             while (!(msg = reader.readLine()).equalsIgnoreCase("exit")) {  
  19.                 // 产生一个InetAddress,内容是服务器端的IP  
  20.                 InetAddress serverAddress = InetAddress.getByName("127.0.0.1");  
  21.                 // 构造要发送消息的数据报, 并制定服务器监听的端口  
  22.                 DatagramPacket packet = new DatagramPacket(msg.getBytes(),  
  23.                         msg.getBytes().length, serverAddress, 1234);  
  24.                 // 发送数据报  
  25.                 socket.send(packet);  
  26.             }  
  27.         } catch (SocketException e) {  
  28.             // TODO Auto-generated catch block  
  29.             e.printStackTrace();  
  30.         } catch (IOException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         } finally {  
  34.             socket.close();  
  35.         }  
  36.     }  
  37. }  

TcpServer.java

[java]  view plain copy

  1. package me.bym.tcp;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6. public class TcpServer {  
  7.     public static void main(String[] args) {  
  8.         // 声明一个服务器端socket  
  9.         ServerSocket serverSocket = null;  
  10.         // 声明一个socket来接受客户端连接  
  11.         Socket socket = null;  
  12.         try {  
  13.             int temp;  
  14.             // 定义服务器端socket并指定监听端口  
  15.             serverSocket = new ServerSocket(5937);  
  16.             // 调用阻塞式方法来获取客户端连接的socket  
  17.             socket = serverSocket.accept();  
  18.             // 获取客户端socket的输入流  
  19.             InputStream inputStream = socket.getInputStream();  
  20.             // 读取客户端socket的输入流的内容并输出  
  21.             byte[] buffer = new byte[512];  
  22.             while ((temp = inputStream.read(buffer)) != -1) {  
  23.                 System.out.println(new String(buffer, 0, temp));  
  24.             }  
  25.         } catch (IOException e) {  
  26.             // TODO Auto-generated catch block  
  27.             e.printStackTrace();  
  28.         } finally {  
  29.             try {  
  30.                 socket.close();  
  31.                 serverSocket.close();  
  32.             } catch (IOException e) {  
  33.                 // TODO Auto-generated catch block  
  34.                 e.printStackTrace();  
  35.             }  
  36.         }  
  37.     }  
  38. }  

TcpClient.java

[java]  view plain copy

  1. package me.bym.tcp;  
  2. import java.io.BufferedReader;  
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.io.OutputStream;  
  6. import java.net.Socket;  
  7. import java.net.UnknownHostException;  
  8. public class TcpClient {  
  9.     public static void main(String[] args) {  
  10.         // 声明一个socket  
  11.         Socket socket = null;  
  12.         try {  
  13.             String msg = null;  
  14.             // 产生socket对象,制定服务器地址和服务器监听的端口号  
  15.             socket = new Socket("127.0.0.1", 5937);  
  16.             // 从标准输入(键盘)读取内容,获取socket的输出流,将读取到的内容放入输出流中  
  17.             BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
  18.             OutputStream outputStream = socket.getOutputStream();  
  19.             while (!(msg = reader.readLine()).equalsIgnoreCase("exit")) {  
  20.                 outputStream.write(msg.getBytes());  
  21.             }  
  22.         } catch (UnknownHostException e) {  
  23.             // TODO Auto-generated catch block  
  24.             e.printStackTrace();  
  25.         } catch (IOException e) {  
  26.             // TODO Auto-generated catch block  
  27.             e.printStackTrace();  
  28.         } finally {  
  29.             try {  
  30.                 socket.close();  
  31.             } catch (IOException e) {  
  32.                 // TODO Auto-generated catch block  
  33.                 e.printStackTrace();  
  34.             }  
  35.         }  
  36.     }  
  37. }