Android Basic Season2

###Activity生命周期一###
1.如何在一个应用程序中定义多个Activity
1)定义一个类,继承Activity
2)在该类中,复写Activity中的onCreate方法
3)在AndroidManifest.xml文件中注册该Activity
//例子中在AndroidManifest.xml中注册了SecondActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activity03"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.activity03.MainActivity"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name="com.example.activity03.SecondActivity"
            android:label="SecondActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2.启动一个Activity的方法
1)生成一个意图对象(intent)
2)调用setClass方法设置所要启动的Activity
3)调用startActivity方法启动Activity

public class MainActivity extends Activity {

	private Button button;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.button);
		button.setOnClickListener(new ButtonListener());		
	}

	class ButtonListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			Intent intent = new Intent();
			//setClass函数的第一个参数是一个Context对象
			//Context是一个类,Activity是Context类的子类,也就是说Activity对象可以向上转型为Context对象
			//setClass函数的第二个参数是一个Class对象,在当前场景下,应该传入启动的Activity的class对象
			intent.setClass(MainActivity.this, SecondActivity.class);
			startActivity(intent);			
		}
		
	}

}

3.Android中的back stack(后退栈)
作用:先进后出,只显示栈顶的Activity.当点击后退按钮时,栈顶的Activity移除.用于记录Activity启动的顺序
###Activity生命周期二&三###
###pic1###
1.Activity的生命周期函数
onCreate:在Activity对象被第一次创建时调用
onStart:当Activity变得可见时调用该函数
onResume:当Activity开始准备与用户交互时调用该方法
onPause:当系统即将启动另外一个Activity之前调用该方法
onStop:当前Activity变得不可见时调用该方法
onDestroy:当前Activity被销毁之前将会调用该方法
onRestart:当一个Activity再次启动之前将会调用该方法
2.Activity对象的状态
1)Resumed:Activity对象处于运行状态
2)Paused:另一个Activity位于前端,但是本Activity还可见
3)Stopped:另一个Activity位于前端,完全遮挡本Activity
3.成对的生命周期函数
onCreate Vs. onDestory
onStart Vs. onStop
onResume Vs. onPause
###Intent###
1.Intent对象的基本概念
Intent是Android应用程序组件之一
Intent对象在Android系统当中表示一种意图
Intent当中最重要的内容是Action与data
2.使用Intent在Activity之间传递数据的方法
1)在Activity之间可以通过Intent对象传递数据
2)使用putExtra()系列方法向Intent对象当中存储数据

	class ButtonListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			Intent intent = new Intent();
			intent.setClass(MainActivity.this, OtherActivity.class);
			//使用putExtra()系列方法向Intent对象当中存储数据
			intent.putExtra("com.example.s02e04_intent.Age", 20);
			startActivity(intent);
		}
	}

3)使用getXXXExtra()系列方法从Intent对象中取出数据

public class OtherActivity extends Activity {

	private TextView textView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.other);
		//getIntent获取intent的实例
		Intent intent = getIntent();
		//使用getXXXExtra()系列方法从Intent对象中取出数据
		int age = intent.getIntExtra("com.example.s02e04_intent.Age", 10);
		
		textView =(TextView)findViewById(R.id.textView);
		textView.setText(age+" ");		
	}
}

###线程###
1.MainThread
MainThread即UI线程,UI界面相关的,都显示在MainThread中
主线程之外,原则上不能修改UI,但可以修改Progress bar
主线程通常用于接受用户的输入,将运算的结果发聩给用户
2.Worker Thread
其他的线程叫Worker Thread
对于一些可能阻塞的操作,必须放置在Worker Thread中
###Handler、Looper和MessageQueue的基本原理###
解决线程间通讯
1)Handler负责把消息对象加入到消息队列(MessageQueue)中
2)Looper不停的从消息队列中向外取出消息对象,如果消息队列中没消息,Looper就处于等待状态
3)Looper将找到与消息对象对应的Handler对象
4)Looper调用Handle的handleMessage方法,处理消息对象

public class MainActivity extends Activity {
	
	private Button button;
	private Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button =  (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new ButtonListener());
		handler = new FirstHandler();		
	}

	class ButtonListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//当用户点击按钮时,我们创建一个消息对象,并使用Handler发送该对象
			Message msg = handler.obtainMessage(); //每个消息对象都有对应的Handler对象
			msg.what = 2;
			handler.sendMessage(msg); 
			//上面一行代码将消息对象放置到消息队列当中
			//1.Looper将会从消息队列中将消息对象取出
			//2.Looper将找到与消息对象对应的Handler对象
			//3.Looper将会调用handler对象的handleMessage(Message msg)方法,用于处理消息对象
		}		
	}
	
	class FirstHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
			int what = msg.what;
			System.out.println("what:" + what);
		}		
	}

###通过Handle实现线程间通讯###
1.workerTread发送消息到主线程
在主线程当中实现Handler的handleMessage()方法
在Worker Thread当中通过Handler发送消息

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new ButtonListener());
		textView = (TextView)findViewById(R.id.textViewId);

		handler = new MyHandler();
		
	}
	
	class MyHandler extends Handler{

		@Override
		public void handleMessage(Message msg) {
			System.out.println("handleMessage======>" + Thread.currentThread().getName());
			String s = (String)msg.obj;
			textView.setText(s);
		}
		
	}

	class NetWorkThread extends Thread{
		@Override
		public void run() {
			System.out.println("network------->" + Thread.currentThread().getName());
			//模拟访问网络,所以说当线程运行时,首先休眠2s
			try {
				Thread.sleep(2*1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//变量s的值,模拟从网路中获取的值
			String s = "从网络中获取的数据";
			//textView.setText(s); 错误的,因为只有主线程才能改UI
			Message msg = handler.obtainMessage();
			msg.obj = s;
			//sendMessage()方法,无论是在主线程中发送还是worker thread中发送,都是可以的
			handler.sendMessage(msg);			
		}
		
	}
	
	class ButtonListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			Thread t = new NetWorkThread();
			t.start();
		}
		
	}

2.主线程发送消息到workerTread
Looper->MessageQueue->Thread->Handler一一对应
1)准备Looper对象
2)在WorkerThread中生成一个Handler对象
3)调用Looper的loop方法之后,loop对象将不断的从消息队列中取出消息对象,然后调用handler的handleMessage()方法,处理该消息对象

/***
 * 
 * 在WorkerThread中生成handler,然后在MainThread中使用这个Handler发送消息,通过消息队列,然后由Looper对象
把消息对象取出来,然后在把这个消息对象传递给handle的handleMessage()方法来处理(处于workerThread中)
 *
 */
public class MainActivity extends Activity {
	
	private Button button;
	private Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Message msg = handler.obtainMessage();
				handler.sendMessage(msg);
			}
		});
		
		WorkerThread wt = new WorkerThread();
		wt.start();
	}
	
	class WorkerThread extends Thread{
		@Override
		public void run() {
			//1.准备Looper对象
			Looper.prepare();
			//2.在WorkerThread中生成一个Handler对象
			handler = new Handler(){
				@Override
				public void handleMessage(Message msg) {
					System.out.println("收到了消息对象");
				}
			};
			//3.调用Looper的loop方法之后,loop对象将不断的从消息队列中取出消息对象,然后调用handler的handleMessage()方法,处理该消息对象
			//如果消息队列为空,则该线程阻塞
			Looper.loop();
		}		
	}

###Handler、Looper和MessageQueue的源代码基本关系###
1.ThreadLocal:线程本地变量
执行ThreadLocal对象的set(Object)方法,将会存入一个以当前线程为键的键值对
执行ThreadLocal对象的get()方法,将会根据当前线程对象为键,取出与之对应的值
通过静态变量ThreadLocal,使Looper,MessageQueue,Thread和Handler一一对应
ThreadLocal用于存放键值对(键是当前线程对象,值是Looper对象)
2.Handler的post(Runnabler)方法
1)如何能够把一个Runnable对象放置在消息队列中;实际上是生成了一个Message对象,并将r赋值给Message对象的callback属性,然后再将Message对象放置在消息队列中
2)Looper取出携带r的Message对象之后,干了些什么;取出Message对象后调用disPatchMessage方法,然后判断Message的callback属性是否为空,此时callback属性有值,所以执行handleCallback(Message msg),该方法中执行了msg.callback.run()

//private static Message getPostMessage(Runnable r)
//1.该方法完成了两个操作,第一生成了一个Message对象;第二,将r对象赋值给Message对象的callback属性

//第一个问题:如何能够把一个Runnable对象放置在消息队列中;实际上是生成了一个Message对象,
//并将r赋值给Message对象的callback属性,然后再将Message对象放置在消息队列中
//第二个问题:Looper取出携带r的Message对象之后,干了些什么;取出Message对象后调用disPatchMessage方法,然后判断Message的callback属性是否为空
//此时callback属性有值,所以执行handleCallback(Message msg),该方法中执行了msg.callback.run()
public class MainActivity extends Activity {
	
	private Button button;
	private Handler handler = new Handler();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				TestThread tt = new TestThread();
				tt.start();				
			}
		});		
	}
	
	class TestThread extends Thread{
		@Override
		public void run() {
			//从网络上取回数据
			Runnable r = new Runnable(){
				@Override
				public void run() {
					//这里可以写上更新UI的代码
					String currentThreadName = Thread.currentThread().getName();
					System.out.println("当前线程的名称为:" + currentThreadName);					
				}				
			};	
			//post(r)将r对象放置在消息队列中,Looper对象(主线程)从消息队列中取出r对象
			//我们猜测:取出r对象之后
			//1.Thread t = new Thread(r);
			//2.t.start()
			//根据测试记过可以看出,该思路是错误的
			//我们的问题是Looper取出r对象之后,干了些什么
			//1)第一生成了一个Message对象;将r对象赋值给Message对象的callback属性
			//2)第二将Message对象放到了消息队列中
			handler.post(r);
		}		
	}

###Http协议###
1.HttpClient使用步骤:
1)生成代表客户端的HttpClient对象
2)生成代表请求的HttpGet对象
3)发送请求,获得服务器返回的HttpResponse对象
4)检查响应状态是否正常
5)获取响应对象当中的数据

	private Button button;	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new ButtonListener());		
	}
	
	class ButtonListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//原则:主线程中不能访问网络
			NetworkThread nt = new NetworkThread();
			nt.start();
		}		
	}

	class NetworkThread extends Thread{
		@Override
		public void run() {
			//创建HttpClient
			HttpClient httpClient = new DefaultHttpClient();
			//创建代表请求的对象,参数是访问的服务器地址
			//http://www.marschen.com/data1.html
			HttpGet httpGet = new HttpGet("http://www.marschen.com/data1.html");
			//执行请求,获取服务器返还的响应对象
			try {
				HttpResponse resp = httpClient.execute(httpGet);
				//检查响应的状态是否正常,检查状态码是否等于200
				int code = resp.getStatusLine().getStatusCode();
				if(code == 200){
					//从响应对象中取出数据
					HttpEntity entity = resp.getEntity();
					InputStream in = entity.getContent();
					BufferedReader reader = new BufferedReader(new InputStreamReader(in));
					String line = reader.readLine();
					Log.d("HTTP", "从服务器取得的数据为:" + line);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 					
		}
		
	}

2.HTTP请求头
1)HTTP请求内容分析
Host www.marschen.com        本次请求访问主机地址
Cache-Control no-cache        设置网页缓存的使用方法
Pragma no-cache
Accept image/jpeg, ....        浏览器可以接受的数据类型
User-Agent   Mozilla/4.0        主要表示客户端类型
Accept-Encoding gzip, deflate   浏览器能够解码的数据编码方式
Accept-Language en-US           浏览器期望的接受的语言种类
2)HTTP响应内容分析
Content-Encoding    返回数据的压缩格式
Content-Length     返回数据量的大小
Content-Type     返回数据的类型
Last-Modified       资源最后一次修改时间
Date                返回数据的时间
Server              服务器类型
3)HTTP请求头与响应头的读取

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button)findViewById(R.id.buttonId);
		button.setOnClickListener(new ButtonListener());		
	}
	
	class ButtonListener implements OnClickListener{
		@Override
		public void onClick(View v) {
			//原则:主线程中不能访问网络
			NetworkThread nt = new NetworkThread();
			nt.start();
		}		
	}

	class NetworkThread extends Thread{
		@Override
		public void run() {
			//创建HttpClient
			HttpClient httpClient = new DefaultHttpClient();
			//创建代表请求的对象,参数是访问的服务器地址
			//http://www.marschen.com/data1.html
			HttpGet httpGet = new HttpGet("http://www.marschen.com/data1.html");
			httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.8");			
			Header [] reqHeaders = httpGet.getAllHeaders();
			for(int i=0; i<reqHeaders.length; i++){
				String name = reqHeaders[i].getName();
				String value = reqHeaders[i].getValue();
				
				Log.d("Http01","request header--Name:" + name + ",value" + value);
			}
			//执行请求,获取服务器返还的响应对象
			try {
				HttpResponse resp = httpClient.execute(httpGet);
				Header[] respHeaders = resp.getAllHeaders();
				for(int i=0; i<respHeaders.length; i++){
					String name = respHeaders[i].getName();
					String value = respHeaders[i].getValue();
					
					Log.d("Http01","response header--Name:" + name + ",value" + value);
				}
				
				//检查响应的状态是否正常,检查状态码是否等于200
				int code = resp.getStatusLine().getStatusCode();
				if(code == 200){
					//从响应对象中取出数据
					HttpEntity entity = resp.getEntity();
					InputStream in = entity.getContent();
					BufferedReader reader = new BufferedReader(new InputStreamReader(in));
					String line = reader.readLine();
					Log.d("HTTP", "从服务器取得的数据为:" + line);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 					
		}
		
	}

3.Get与Post方法
1)GET--类似明信片
从服务器取回数据
使用GET方法向服务器提交的数据量小,通常不超过2K
GET请求是将所要提交的数据附在URL之后
2)POST--类似信
向服务器提交数据
使用POST向服务器提交的数据量通常没有限制
POST请求是将提交的数据放置在请求的请求体中
3)POST提交数据的步骤
a.构造请求对象
b.将需要传递给服务器端的数据放置在键值对对象当中
c.将准备好的键值对放置在List当中;
d.生成代表请求体的对象;
e.将存有请求键值对的List对象放置在请求题对象当中;
f.将请求体对象放置到请求对象当中;
g.发送请求对象

public class MainActivity extends ActionBarActivity {

	private EditText nameText;
	private EditText pwdText;
	private Button button;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		nameText = (EditText) findViewById(R.id.nameText);
		pwdText = (EditText) findViewById(R.id.pwdText);
		button = (Button) findViewById(R.id.submitButton);

		button.setOnClickListener(new ButtonListener());
	}

	class ButtonListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			String name = nameText.getText().toString();
			String pwd = pwdText.getText().toString();

			//使用GET方法向服务器发送请求
//			GetThread gt = new GetThread(name, pwd);
//			gt.start();
			
			//使用POST方法向服务器发送请求
			PostThread pt = new PostThread(name, pwd);
			pt.start();
		}
	}

	//该线程使用POST方法向服务器发送请求
	class PostThread extends Thread {

		String name;
		String pwd;

		public PostThread(String name, String pwd) {
			this.name = name;
			this.pwd = pwd;
		}

		@Override
		public void run() {
			HttpClient httpClient = new DefaultHttpClient();
			String url = "http://192.168.1.103:8080/s02e14.jsp";
			//生成使用POST方法的请求对象
			HttpPost httpPost = new HttpPost(url);
			//NameValuePair对象代表了一个需要发往服务器的键值对
			NameValuePair pair1 = new BasicNameValuePair("name", name);
			NameValuePair pair2 = new BasicNameValuePair("password", pwd);
			//将准备好的键值对对象放置在一个List当中
			ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
			pairs.add(pair1);
			pairs.add(pair2);
			try {
				//创建代表请求体的对象
				HttpEntity requestEntity = new UrlEncodedFormEntity(pairs);
				//将请求体放置在请求对象当中
				httpPost.setEntity(requestEntity);
				//执行请求对象
				try {
					HttpResponse response = httpClient.execute(httpPost);
					if (response.getStatusLine().getStatusCode() == 200) {
						HttpEntity entity = response.getEntity();
						BufferedReader reader = new BufferedReader(
								new InputStreamReader(entity.getContent()));
						String result = reader.readLine();
						Log.d("HTTP", "POST:" + result);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	class GetThread extends Thread {

		String name;
		String pwd;

		public GetThread(String name, String pwd) {
			this.name = name;
			this.pwd = pwd;
		}

		@Override
		public void run() {
			HttpClient httpClient = new DefaultHttpClient();
			String url = "http://192.168.1.103:8080/s02e14.jsp?name=" + name+ "&password=" + pwd;
			HttpGet httpGet = new HttpGet(url);
			try {
				HttpResponse response = httpClient.execute(httpGet);
				if (response.getStatusLine().getStatusCode() == 200) {
					HttpEntity entity = response.getEntity();
					BufferedReader reader = new BufferedReader(
							new InputStreamReader(entity.getContent()));
					String result = reader.readLine();
					Log.d("HTTP", "GET:" + result);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值