Android基础学习__第4天__利用HTTP进行数据交互


1.电话联系人的读取与写入

联系人的读取操作:

public void click(View view){

	//1.查询raw_contact表获取联系人的id
	ContentResolver resolver = getContentResolver();
	//获取raw_contact表对应的uri
	Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
	Uri dataUri = Uri.parse("content://com.android.contacts/data");
	Cursor cursor = resolver.query(uri,null,null,null,null);
	while(cursor.moveToNext()){
		//2.根本id查询相关数据
		String id = cursor.getString(cursor.getColumnIndex("contact_id");
		Cursor dataCursor = resolver.query(dataUri,null,"raw_contact_id=?",new String[]{id},null);
		while(dataCursor.moveToNext()){
			String data1 = dataCursor.getString(dataCursor.getColumnIndex("data1"));
			String mimetype = dataCursor.getString(dataCursor.getCloumnIndex("mimetype"));
			System.out.println("data1="+data1);
			System.out.println("mimetype="+mimetype);
		}
		System.out.println("--------------");
	}
	cursor.close();
}
添加一条联系人信息:

public void click(View view) {
	// 1.向raw_contacts添加联系人id
	// 得到中间人
	ContentResolver resolver = getContentResolver();
	Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
	Uri dataUri = Uri.parse("content://com.android.contacts/data");
	ContentValues values = new ContentValues();
	// 必须知道最后一条联系人的id是多少
	Cursor cursor = resolver.query(uri, new String[] { "_id" }, null, null,null);
	cursor.moveToLast();
	int lastId = cursor.getInt(0);
	int newId = lastId + 1;
	System.out.println(newId);
	values.put("contact_id", newId);
	resolver.insert(uri, values);

	// 2.使用添加的联系人的id,向data表里面添加数据
	// 添加电话号码
	ContentValues phoneValues = new ContentValues();
	phoneValues.put("data1", "51965567654");
	phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2");
	phoneValues.put("raw_contact_id", newId);
	resolver.insert(dataUri, phoneValues);

	// 添加邮箱
	ContentValues emailValues = new ContentValues();
	emailValues.put("data1", "hiahia@itheima.com");
	emailValues.put("mimetype", "vnd.android.cursor.item/email_v2");
	emailValues.put("raw_contact_id", newId);
	resolver.insert(dataUri, emailValues);
	
	// 添加名称
	ContentValues nameValues = new ContentValues();
	nameValues.put("data1", "hiahia");
	nameValues.put("mimetype", "vnd.android.cursor.item/name");
	nameValues.put("raw_contact_id", newId);
	resolver.insert(dataUri, nameValues);

	Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
}

2.网络图片查看器

查看指定路径图片并缓存进本地:

public void click(View view) {
	final String path = et_path.getText().toString().trim();
	if (TextUtils.isEmpty(path)) {
		Toast.makeText(this, "图片路径不能为空", 0).show();
		return;
	} else {
		// 查看图片的时候 首先检测图片是否存在
		File file = new File(getCacheDir(), getFileName(path));
		if (file.exists() && file.length() > 0) {
			// 加载缓存图片
			Log.i(TAG, "加载缓存图片");
			iv.setImageURI(Uri.fromFile(file));
		} else {
			Log.i(TAG, "下载新图片,并且缓存");
			new Thread() {
				public void run() {
					try {
						URL url = new URL(path);
						// 获取一个http的连接
						HttpURLConnection conn = (HttpURLConnection) url
								.openConnection();
						// 设置http的请求方式 get / post 注意单词 大写
						conn.setRequestMethod("GET");
						conn.setConnectTimeout(5000);
						// conn.setReadTimeout(5000);
						// 原因: 访问网络 耗时的操作 需要一定的时间 为了避免界面卡死 无响应 4.0系统做了一个处理
						// 所有的网络访问的操作 是不可以在主线程里面执行.
						conn.setRequestProperty(
								"User-Agent",
								"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; Shuame)");
						int code = conn.getResponseCode();
						if (code == 200) {
							// 得到服务器返回的输入流
							InputStream is = conn.getInputStream();
							File file = new File(getCacheDir(),
									getFileName(path));
							FileOutputStream fos = new FileOutputStream(
									file);
							byte[] buffer = new byte[1024];
							int len = 0;
							while ((len = is.read(buffer)) != -1) {
								fos.write(buffer, 0, len);
							}
							is.close();
							fos.close();
							Bitmap bitmap = BitmapFactory.decodeFile(file
									.getAbsolutePath());
							// iv.setImageBitmap(bitmap);
							// 在子线程里面 需要更新ui
							// 通知主线程 更新一下ui
							Message msg = new Message();
							msg.what = SET_IMAGE;
							msg.obj = bitmap;
							handler.sendMessage(msg);
						} else {
							Message msg = new Message();
							msg.what = ERROR;
							handler.sendMessage(msg);
						}
					} catch (Exception e) {
						Message msg = new Message();
						msg.what = ERROR;
						handler.sendMessage(msg);
						e.printStackTrace();
					}
				};
			}.start();
		}
	}
}

/**
 * 获取图片的名称
 * 
 * @param path
 * @return
 */
public String getFileName(String path) {
	int start = path.lastIndexOf("/") + 1;
	return path.substring(start);
}

    anr产生原理

    anr是指application not response,应用程序无响应。产生原因:主线程需要做很多重要的事情,响应点击事件,更新ui,在主线程里面阻塞过久的时间,应用程序就会无响应,为了避免应用程序出现anr,所有的耗时的操作都应该放在子线程里面执行。

    Handler入门

    由于Android特殊机制,Android中子线程是不允许操作UI界面,所以为了子线程与主线程之间的通信,Android中提供了Handler来解决这个问题。

    使用方法:1.在主线程中实例化一个Handler对象,覆写handlerMessage方法。

              2.子线程中在需要使用到主线程操作相关UI更新或者其他操作的地方,实例化一个Message对象,调用handler中的sendMessage方法并将Message的对象传入进行相关操作,示例源码如上。

    内部实现原理:1.初始化Handler。在Hanlder初始化的时候,它会去获取对应UI线程的Looper,如果没有Looper,UI线程则会通过ThreadLocal创建一个Looper,而这个Looper则会创建一个用于存储消息的消息池。如果有Looper,则会使用该UI线程对应的Looper。

    2.创建消息。在创建一个消息的时候,Handler会判断消息池中是否有消息,如果没有则创建,这样使用消息池的好处就是消息可以被重复使用,不会被作为垃圾而被系统回收

    3.发送消息。由于Handler已持有UI线程的Looper与对应的消息池(MessageQuece),子线程通过Handler中的sendMessage将消息发送至消息池。

    4.处理消息。Looper是一个消息循环获取的实例,如果消息池没有消息,它会一直循环等待,如果发现消息,UI线程则会调用Handler的handlerMessage方法处理消息

3.网络html查看器

public void click(View view){
	final String path = et_path.getText().toString().trim();
	if(TextUtils.isEmpty(path)){
		Toast.makeText(this, "路径不能为空", 0).show();
		return;
	}else{
		//联网
		new Thread(){
			public void run() {
				try {
					URL url = new URL(path);
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					conn.setRequestMethod("GET");
					conn.setConnectTimeout(5000);
					int code = conn.getResponseCode();
					if(code ==200){
						InputStream is = conn.getInputStream();
						String body = StreamUtils.readStream(is);
						Message msg = Message.obtain();
						msg.obj = body;
						msg.what = SHOW_HTML;
						handler.sendMessage(msg);		
					}else{
						Message msg = Message.obtain(); 
						msg.what = ERROR;
						handler.sendMessage(msg);
					}
				} catch (Exception e) {
					e.printStackTrace();
					Message msg = Message.obtain(); 
					msg.what = ERROR;
					handler.sendMessage(msg);
				}		
			};
		}.start();	
	}
}
StreamUtils类:
public class StreamUtils {
	
	/**
	 * 把一个输入流里面的内容 转化成文本 字符串
	 * @param is
	 * @return
	 */
	public static String readStream(InputStream is){
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int len = 0;
			byte[] buffer = new byte[1024];
			while((len = is.read(buffer))!=-1){
				baos.write(buffer, 0, len);
			}
			is.close();
			baos.close();
			byte[] result = baos.toByteArray();//服务器端返回的0011  gb2312
			return new String(result,"gb2312");
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
}

4.采用Get/Post方式提交数据

利用HttpURLConnection对象,我们可以从网络中获取网页数据.
public class LoginService {
	/**
	 * GET方式登陆到服务器
	 * 
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return 服务器返回的消息
	 */
	public static String loginByGet(String username, String password) {
		//数据最大长度  4kb
		String path = "http://192.168.1.100:8080/web/LoginServlet?username="
				+ URLEncoder.encode(username) + "&password=" + URLEncoder.encode(password);
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5000);

			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream();
				String result = StreamUtils.readStream(is);
				return result;
			} else {
				return null;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * POST方式登陆到服务器
	 * 
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return 服务器返回的消息
	 */
	public static String loginByPost(String username, String password) {
		
		//流的方式写给服务器 没有最大长度限制的.
		String path = "http://192.168.1.100:8080/web/LoginServlet";
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			//1.设置请求方式 为 post
			conn.setRequestMethod("POST");
			//2. 设置请求的头  
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			String data = "username="+URLEncoder.encode(username)+"&password="+URLEncoder.encode(password);
			conn.setRequestProperty("Content-Length", String.valueOf(data.length()));
			
			conn.setConnectTimeout(5000);
			//3.设置 允许向服务器写数据
			conn.setDoOutput(true);
			
			//4.把数据写给服务器
			conn.getOutputStream().write(data.getBytes());

			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream();
				String result = StreamUtils.readStream(is);
				return result;
			} else {
				return null;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
保证提交数据的编码与服务器所接受的编码要统一并且要使用能解析中文的编码,不然会出现中文乱码问题。

5.采用httpclient提交数据到服务器

/*
 * 采用httpclient get提交数据
 *
 * @return 返回Null 登陆异常
 */
public static String loginByClientGet(String username,String password){
	try{
		//1.打开一个浏览器
		HttpClient client = new DefaultHttpClient();

		String path = "http://192.168.1.100:8080/web/LoginServlet?username="  
			+ URLEncoder.encode(username) + "&password=" + URLEncoder.encode(password);  
		//2.输入地址
		HttpGet httpGet = new HttpGet(path);
		//3.敲回车
		HttpResponse response = client.excute(httpGet);
		int code = response.getStatusLine().getStatusCode();
		if (code == 200) { 
			InputStream is = response.getEntity().getContent();
			String result = StreamUtils.readStream(is);  
			return result;  
		} else {  
			return null;  
		}
	}catch(Exception e){
		e.printStackTrace();
		return null;
	}
}

/*
 * 采用httpclient post提交数据
 *
 * @return 返回Null 登陆异常
 */
public static String loginByClientPost(String username,String password){

	try{
		//1.打开一个浏览器
		HttpClient client = new DefaultHttpClient();

		String path = "http://192.168.1.100:8080/web/LoginServlet";  
		//2.输入地址
		HttpPost httpPost = new HttpPost(path);
		List<NameValuePair> parameters = new ArrList<NameValuePair>();
		parameters.add(new BasicNameValuePair("username",username);
		parameters.add(new BasicNameValuePair("paseword",paseword);
		httpPost.setEntity(new UriEncodedFormEntity(,"UTF-8");

		//3.敲回车
		HttpResponse response = client.excute(httpPost);
		int code = response.getStatusLine().getStatusCode();
		if (code == 200) { 
			InputStream is = response.getEntity().getContent();
			String result = StreamUtils.readStream(is);  
			return result;  
		} else {  
			return null;  
		}
	}catch(Exception e){
		e.printStackTrace();
		return null;
	}
}

6.异步http框架提交数据

    AsyncHttpClient是实现异步请求的开源框架,下面测试简单使用方法:

Get方式:

public void click(View view) {
	// 用户名 密码 提交到服务器.
	AsyncHttpClient client = new AsyncHttpClient();
	String path = "http://192.168.1.100:8080/web/LoginServlet?username="
		+ URLEncoder.encode("zhangsan") + "&password="
		+ URLEncoder.encode("1234");
	client.get(path, new AsyncHttpResponseHandler() {
		@Override
		public void onSuccess(String content) {
			super.onSuccess(content);
			Toast.makeText(MainActivity.this, "请求成功:" + content, 0).show();
		}

		@Override
		public void onFailure(Throwable error, String content) {
			// TODO Auto-generated method stub
			super.onFailure(error, content);
			Toast.makeText(MainActivity.this, "请求失败:" + content, 0).show();
		}
	});
}
Post方式:
public void click5(View view) {
	final String username = et_username.getText().toString().trim();
	final String password = et_password.getText().toString().trim();
	AsyncHttpClient client = new AsyncHttpClient();
	String url = "http://192.168.1.100:8080/web/LoginServlet";
	RequestParams params = new RequestParams();
	params.put("username", username);
	params.put("password", password);
	client.post(url, params, new AsyncHttpResponseHandler() {

		@Override
		public void onSuccess(String content) {
			super.onSuccess(content);
			Toast.makeText(MainActivity.this, content, 0).show();
		}
	});
}
上传文件:
public void click(View view) {
	String path = et_path.getText().toString().trim();
	File file = new File(path);
	if (file.exists() && file.length() > 0) {

		AsyncHttpClient client = new AsyncHttpClient();
		RequestParams params = new RequestParams();
		try {
			params.put("profile_picture",file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} // Upload a File
		client.post("http://192.168.1.100:8080/web/UploadFileServlet",
				params, new AsyncHttpResponseHandler(){

					@Override
					public void onSuccess(String content) {
						Toast.makeText(MainActivity.this, "上传成功", 1).show();
						super.onSuccess(content);
					}

					@Override
					public void onFailure(Throwable error, String content) {
						Toast.makeText(MainActivity.this, "上传失败", 1).show();
						super.onFailure(error, content);
					}
				});
	}else{
		Toast.makeText(this, "文件不存在", 1).show();
	}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值