Android基础学习笔记(四)之网络编程(1)

  1、网页源码查看器
  Shift+F2  调用Httpwatch
  
  HttpURLConnection: 用于发送或接受接收数据
  联网应用需要赋予联网权限INTRENET
  ScrollView 只能有一个孩子,但是里面的孩子可以是一个布局
  
public class MainActivity extends ActionBarActivity {

	private EditText et_path;
	private TextView tv_result;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//1、获取我们关心的组件
		et_path = findViewById(R.id.et_path);
		tv_result = findViewById(R.id.tv_result);
	}
	public void click(View v) {
		//2.1、获取源代码路径
		String path = et_path.getText().toString().trim();
		
		try {
			//2.2、创建URL 对象 指定我们要访问的网址
			URL url = new URL(path);
			
			//2.3、拿HttpUrlConnection对象
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			
			//2.4、设置发送get请求
			connection.setRequestMethod("GET");//get要求大写,默认是get请求你
			//2.5、设置请求的超时时间
			connection.setConnectTimeout(5000);
			
			//2.6、获取服务器返回的状态码
			int responseCode = connection.getResponseCode();
			//2.7、如果responseCode==200 ,请求成功
			if(responseCode == 200) {
				//2.8、获取服务器返回的数据 是以流的形式返回的,由于流装换为字符串是一个非常常见的操作 索引抽出一个工具类Utils
				InputStream in = connection.getInputStream();
				
				//2.9、使用定义的工具类来把in转为String
				String text = StringTool.readStram(in);
				//2.9、把流的数据展示到textview上
				tv_result.setText(text);
				
			}
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
2、消息机制的写法
  【1】anr   Application  not  response   应用无响应  主线程(UI线程)
  【2】如果在主线程中进行了耗时操作,就会报anr异常(比如连接网络,拷贝大数据,睡眠)
  【3】避免anr k可以吧耗时操作 放在子线程中   自己再创建一个主线程
  【4】在Android4.0之后,运行联网项目会报错(android.os.NetworkOnMainThreadException),
      这是因为4.0之后,谷歌强制要求连接网络不能放在主线程进行访问
  【5】只有主线程才能更新UI
  【6】Android的消息机制
3、handler原理
  Handler使用步骤
    【1】在主线程定义一个Handler
     private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			tv_result.setText((String)msg.obj);
		}; 
	};

    【2】使用Handler 会重写Handler里面的handleMessage 方法(如上述代码)

    【3】拿着我在主线程创建的Handler去子线程发消息  

      handler.sendMessage(msg);

     【4】一发消息handleMessage方法就会执行

        Handler的作用:是用于发消息和处理消息的

        Looper是去消息队列中取消息,取完消息交给Handler,

        Looper是在主线程一创建  Looper就有了

        

4、使用Handler和子线程优化后的联网小应用

public class MainActivity extends ActionBarActivity {

	protected static final int REQUESTSUCCESS = 0;
	protected static final int REQUSETFAILURE = 1;
	protected static final int REQUESTEXCEPTION = 2;
	private EditText et_path;
	private TextView tv_result;
	
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if(msg.what == REQUESTSUCCESS) {
				tv_result.setText((String)msg.obj);
			}else if(msg.what == REQUSETFAILURE){
				Toast.makeText(getApplicationContext(), "请求资源不存在", 1).show();
			}else if(msg.what == REQUESTEXCEPTION){
				Toast.makeText(getApplicationContext(), "服务器忙,请稍后尝试.........", 1).show();
			}
		}; 
	};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//1、获取我们关心的组件
		et_path = findViewById(R.id.et_path);
		tv_result = findViewById(R.id.tv_result);
	}
	public void click(View v) {
		//2.0、创建一个子线程
		new Thread() {
			public void run() {
				
				//2.1、获取源代码路径
				String path = et_path.getText().toString().trim();
				
				try {
					//2.2、创建URL 对象 指定我们要访问的网址
					URL url = new URL(path);
					
					//2.3、拿HttpUrlConnection对象
					HttpURLConnection connection = (HttpURLConnection) url.openConnection();
					
					//2.4、设置发送get请求
					connection.setRequestMethod("GET");//get要求大写,默认是get请求你
					//2.5、设置请求的超时时间
					connection.setConnectTimeout(5000);
					
					//2.6、获取服务器返回的状态码
					int responseCode = connection.getResponseCode();
					//2.7、如果responseCode==200 ,请求成功
					if(responseCode == 200) {
						//2.8、获取服务器返回的数据 是以流的形式返回的,由于流装换为字符串是一个非常常见的操作 索引抽出一个工具类Utils
						InputStream in = connection.getInputStream();
						
						//2.9、使用定义的工具类来把in转为String
						String text = StringTool.readStram(in);
						
						//2.9.0、创建Message对象
						Message msg = new Message();
						msg.obj = text;
						msg.what = REQUESTSUCCESS;
						//2.9.1、使用handler
						//发一条消息,消息中有数据,有数据在msg中,handleMessage方法会执行,这个方法在主线程
						handler.sendMessage(msg);
						//2.9、把流的数据展示到textview上,更新UI逻辑
						//tv_result.setText(text);
						
					}else {
						//请求资源不存在
						//Toast是一view ,不能再子线程展示
						Message msg = new Message();
						msg.what = REQUSETFAILURE;//代表哪条消息
						handler.sendMessage(msg);
						
					}
					
				}  catch (Exception e) {
					
					e.printStackTrace();
					//异常时发送消息
					Message msg = new Message();
					msg.what = REQUESTEXCEPTION;
					handler.sendMessage(msg);
				}
			}; 
			
			
		}.start();;
		
	}

}

   规则:只要是耗时的操作,就开一个子线程,获取数据后想要更新UI 就使用Handler

5、图片查看器

  BitFactory类(Creates Bitmap objects from various sources, including files, streams, and byte-arrays.) 

static Bitmap decodeStream(InputStream is)

Decode an input stream into a bitmap.

  【1】把流信息转换成BitMap对象

  【2】BitFactory.decodeStream(inputStream)

  【3】记得加上网络访问权限

6、使用cache优化后的代码

public class MainActivity extends ActionBarActivity {

	protected static final int REQUESTSUCCESS = 0;
	protected static final int REQUSETFAILURE = 1;
	protected static final int REQUESTEXCEPTION = 2;
	private EditText et_path;
	private ImageView iv_result;
	
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			Bitmap bitmap = (Bitmap) msg.obj;
			iv_result.setImageBitmap(bitmap);
		};
	};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//1、获取我们关心的组件
		et_path = findViewById(R.id.et_path);
		iv_result = findViewById(R.id.iv_result);
	}
	public void click(View v) {
		
		
		//创建子线程
		new Thread() {
			
			@Override
			public void run() {
				//2.1获取访问图片路径
				String path = et_path.getText().toString().trim();
				
				
				try {
					
					File file = new File(getCacheDir(),"test.jpg");
					if(file.exists()&&file.length()>0) {
						//
						System.out.println("使用缓存图片");
						Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
						Message obtain = Message.obtain();
						obtain.obj =  bitmap;
						handler.sendMessage(obtain);
						
					}else {
						System.out.println("第一次访问");
						//2.2、创建URL对象
						URL url = new URL(path);
						
						//2.3、获取httpurlconnection
						
						HttpURLConnection connection = (HttpURLConnection) url.openConnection();
						
						//2.4、设置请求方式
						connection.setRequestMethod("GET");
						//2.5、设置超时时间
						connection.setConnectTimeout(5000);
						//2.6、获取返回状态码
						int code = connection.getResponseCode();
						if(code == 200) {
							//2.7、获取图片的数据,不管什么数据,都是以流的形式返回
							InputStream in = connection.getInputStream();
							
							//2.7.1、缓存图片,谷歌提供缓存目录
						
							FileOutputStream fos = new FileOutputStream(file);
							int len =-1;
							byte[] bytes = new byte[1024];
							while((len = in.read(bytes))!=-1) {
								fos.write(bytes);
							}
							fos.close();
							in.close();
							
							//2.8、通过位图工厂获取bitmap
							Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
							//Bitmap bitmap = BitmapFactory.decodeStream(in);
							//位图,bitMap 
							//更新UI逻辑,找Handler
							Message msg = Message.obtain();//使用Message的静态方法可以减少对象的创建
							msg.obj = bitmap;
							msg.what = REQUESTSUCCESS;
							handler.sendMessage(msg);
							
						}
					}
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}.start();
	}

}

 7、cache目录和FileDir区别

  重要数据不放在cache中

8、runOnUIThread  api介绍

    【1】如果仅仅是更新UI 那么就使用runOnUIThread

    【2】有时可以根据Handler 携带数据

9、常见消息  API

    【1】定时执行某个语句 

		new Handler().postDelayed(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("哈哈哈哈哈哈哈........");
				
			}
		}, 5000);
	}

        Timer也可以实现

void schedule(TimerTask task, long delay)

Schedules the specified task for execution after the specified delay.

    【2】3秒后,每隔一秒执行一次,可调用cancel方法取消

		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			
			@Override
			public void run() {
				System.out.println("哈哈哈哈哈哈哈哈哈....");
			}
		}, 3000,1000);

    【3】Handler和Timer的区别

       Handler里面run方法可以更新UI

       Timer里面的run方法不能更新UI

10、新闻客户端

  【1】UI效果美工制作

  【2】应用的传输数据  定义接口

  【3】关于xml数据,是服务器开发人员通过一定的技术手段返回 Android开发人员只需解析

 11、开源项目smartimageview介绍

  【1】把com包拷贝到当前工程

  【2】在使用smartimageview时 在布局里面定义 一定包含整个包名+类名

  【3】开源项目smartImageView下载网址,https://github.com/Robin-Yang/SmartImageView.git

原文地址:https://www.cnblogs.com/lyhcc/p/10319467.html