andriod开发,简单的封装网络请求并监听返回.

一.为什么封装

因为android 4.0 以后的发送网络请求必须要放到异步线程中,而异步线程必须跟handle合作才能更新主线程中的UI,所以建议用一个类继承handler来异步处理网络请求.

二.封装哪些功能.

首先,每次发送网络请求都需要先检测网络连接是否正常.其次需要向用户提供一个提示信息,比如ProgressDialog,然后简单粗暴的把网络请求结果设为3种:1->请求成功;2->请求失败;3->连接超时.请求成功的话就返回正确的结果,请求失败就提示网络请求失败.请求超时就询问是否重连.所以需要封装的就有:

1.检测网络

/**

	 * 判断网络连接

	 */

	private boolean isNetworkConnect() {

		ConnectivityManager cm = (ConnectivityManager) activity

				.getSystemService(Context.CONNECTIVITY_SERVICE);

		cm.getActiveNetworkInfo();

		if (cm.getActiveNetworkInfo() != null) {

			return cm.getActiveNetworkInfo().isAvailable();

		}

		return false;

	}



	/**

	 * 打开网络对话框

	 */

	private void whetherOpenNet() {

		if (dialog != null) {

			dialog.cancel();

			dialog = null;

		}

		AlertDialog.Builder builder = new AlertDialog.Builder(activity);

		builder.setTitle("网络木有连接");

		builder.setMessage("是否打开网络连接");

		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {



			@Override

			public void onClick(DialogInterface dialog, int which) {

				activity.startActivityForResult(new Intent(

						Settings.ACTION_WIRELESS_SETTINGS), OPEN_NETWORK);

			}

		});

		builder.setNegativeButton("取消", null);

		dialog = builder.create();

		dialog.show();

	}

2.进度条提示

/**

	 * 显示进度条提示

	 * 

	 * @param message

	 */

	private void showPd(String message) {

		showLog("start connect");

		if (message == null || message.length() == 0) {

			return;

		}

		if (pd != null) {

			pd.cancel();

			pd = null;

		}

		pd = new ProgressDialog(activity);

		pd.setMessage(message);

		pd.setOnCancelListener(new OnCancelListener() {



			@Override

			public void onCancel(DialogInterface dialog) {

				requestThread.interrupt();

			}

		});

		pd.setCancelable(true);

		pd.show();

	}

3.处理请求结果

 

 

/**

	 * 发起一个post请求,返回string对象

	 * 

	 * @param stringListener

	 * @param isLoadCache

	 *            true 为加载缓存,false为不加载缓存

	 */

	public void postRequest(final String text,

			final RequestStringListener stringListener) {

		if (!isNetworkConnect()) {

			whetherOpenNet();

			return;

		}

		showPd(text);

		Runnable task = new Runnable() {



			@Override

			public void run() {

				try {

					final String result = postStringResult();

					if (requestThread.isInterrupted()) {

						showLog("is interrupted");

						return;

					}

					if (result == null) {

						netError();

						return;

					}

					post(new Complete() {



						@Override

						public void run() {

							super.run();

							stringListener.onComplete(result);

							sendEmptyMessage(REQUEST_SUCCESS);

						}

					});

				} catch (SocketTimeoutException e) {

					timeOut(text, stringListener);

					e.printStackTrace();

				} catch (Exception e) {

					netError();

					e.printStackTrace();

				}



			}

		};

		requestThread = new Thread(task);

		requestThread.start();

	}



	/**

	 * 网络连接超时

	 * 

	 * @param text

	 * @param stringListener

	 */

	protected void timeOut(final String text,

			final RequestStringListener stringListener) {

		sendEmptyMessage(REQUEST_TIMEOUT);

		Looper.prepare();

		post(new Complete() {



			@Override

			public void run() {

				super.run();

				new AlertDialog.Builder(activity)

						.setTitle("网络连接超时")

						.setNegativeButton("取消", null)

						.setPositiveButton("重连",

								new DialogInterface.OnClickListener() {



									@Override

									public void onClick(DialogInterface dialog,

											int which) {

										showLog("重连");

										postRequest(text, stringListener);

									}

								}).show();

			}

		});



	}



	/**

	 * 网络连接错误或返回数据为空

	 * 

	 */

	protected void netError() {

		sendEmptyMessage(REQUEST_ERROR);

		Looper.prepare();

		post(new Complete() {



			@Override

			public void run() {

				super.run();

				if (!isNetworkConnect()) {

					whetherOpenNet();

				} else {

					Toast.makeText(getActivity(), "网络连接失败,请稍后重试",

							Toast.LENGTH_LONG).show();

				}

			}

		});

	}

三.使用

 

 

封装完成后就可以使用了.

 

NetApi netApi = new NetApi(MainActivity.this,

				"http://192.168.10.233:8089/web_test/json");

		netApi.addParams("test", "test");

		netApi.postRequest("测试请求", new RequestStringListener() {



			@Override

			public void onComplete(String result) {

				Log.d("test", "result is --->" + result);

			}

		});

 

四.贴出完整代码

package com.example.test_android;



import java.io.BufferedReader;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.net.HttpURLConnection;

import java.net.SocketTimeoutException;

import java.net.URL;

import java.net.URLEncoder;

import java.util.HashMap;

import java.util.Map;



import org.json.JSONException;



import android.app.Activity;

import android.app.AlertDialog;

import android.app.ProgressDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.content.DialogInterface.OnCancelListener;

import android.content.Intent;

import android.net.ConnectivityManager;

import android.os.Handler;

import android.os.Looper;

import android.provider.Settings;

import android.util.Log;

import android.widget.Toast;



/**

 * 网络接口,post请求string或者get请求json,里面只包含一个线程,只能同时发送一个网络请求

 * 

 * @author oldfeel

 * 

 */

public class NetApi extends Handler {

	/** 打开网络连接 */

	public static final int OPEN_NETWORK = -1;

	/** 请求成功 */

	public static final int REQUEST_SUCCESS = 1;

	/** 请求失败 */

	public static final int REQUEST_ERROR = 2;

	/** 网络连接超时 */

	public static final int REQUEST_TIMEOUT = 3;

	/** 超时时间限制 */

	private static final int TIME_OUT = 30 * 1000;

	private Activity activity;

	private Map<String, String> params = new HashMap<String, String>();

	private String path = "";

	private ProgressDialog pd;

	private Thread requestThread;

	private AlertDialog dialog;



	/**

	 * 构造一个netapi对象

	 * 

	 * @param context

	 * 

	 * @param path

	 *            这次请求需要调用的url

	 */

	public NetApi(Activity activity, String path) {

		this.activity = activity;

		this.path = path;

	}



	/**

	 * 添加参数,用url编码格式

	 * 

	 * @param key

	 * @param value

	 */

	public void addParams(String key, Object value) {

		if (!isEmpty(key) && !isEmpty(value)) {

			params.put(key.trim(), value.toString().trim());// *.trim(),取消首尾空格

		}

	}



	/**

	 * 补充路径,比如添加 /信息类别id/新闻id

	 * 

	 * @param objects

	 */

	public void addPath(Object... objects) {

		for (Object object : objects) {

			path = path + "/" + getUrlEncode(object);

		}

	}



	/**

	 * 检查该参数是否有内容,没有的话就不用添加了

	 * 

	 * @param str

	 * @return true为没有内容,false为有内容

	 */

	public boolean isEmpty(Object str) {

		if (str == null || str.toString().length() == 0)

			return true;

		else

			return false;

	}



	/**

	 * 获取url编码的字符串

	 * 

	 * @param value

	 * @return

	 */

	private String getUrlEncode(Object value) {

		try {

			return URLEncoder.encode(value.toString().trim(), "utf-8");

		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();

		}

		return null;

	}



	/**

	 * get请求,拼接url路径,并对参数进行urlencode

	 */

	public String getPath() {

		if (params.size() == 0) {

			return path;

		}

		StringBuilder sb = new StringBuilder();

		boolean first = path.indexOf("?") == -1; // 不包含?(first=true)说明是第一次添加参数,包含?说明url中带有参数

		for (String key : params.keySet()) {

			if (first) {

				first = false;

				sb.append("?");

			} else {

				sb.append("&");

			}

			sb.append(key + "=" + getUrlEncode(params.get(key)));

		}

		return path + sb.toString();

	}



	/**

	 * post请求,传入的参数

	 * 

	 * @return

	 */

	private String postParams() {

		if (params.size() == 0) {

			return path;

		}

		boolean isFrist = true;

		StringBuilder sb = new StringBuilder();

		for (String key : params.keySet()) {

			if (isFrist) {

				sb.append(key + "=" + params.get(key));

				isFrist = false;

			} else {

				sb.append("&" + key + "=" + params.get(key));

			}

		}

		return sb.toString();

	}



	/**

	 * 显示进度条提示

	 * 

	 * @param message

	 */

	private void showPd(String message) {

		showLog("start connect");

		if (message == null || message.length() == 0) {

			return;

		}

		if (pd != null) {

			pd.cancel();

			pd = null;

		}

		pd = new ProgressDialog(activity);

		pd.setMessage(message);

		pd.setOnCancelListener(new OnCancelListener() {



			@Override

			public void onCancel(DialogInterface dialog) {

				requestThread.interrupt();

			}

		});

		pd.setCancelable(true);

		pd.show();

	}



	/**

	 * 发起一个post请求,返回string对象

	 * 

	 * @param stringListener

	 * @param isLoadCache

	 *            true 为加载缓存,false为不加载缓存

	 */

	public void postRequest(final String text,

			final RequestStringListener stringListener) {

		if (!isNetworkConnect()) {

			whetherOpenNet();

			return;

		}

		showPd(text);

		Runnable task = new Runnable() {



			@Override

			public void run() {

				try {

					final String result = postStringResult();

					if (requestThread.isInterrupted()) {

						showLog("is interrupted");

						return;

					}

					if (result == null) {

						netError();

						return;

					}

					post(new Complete() {



						@Override

						public void run() {

							super.run();

							stringListener.onComplete(result);

							sendEmptyMessage(REQUEST_SUCCESS);

						}

					});

				} catch (SocketTimeoutException e) {

					timeOut(text, stringListener);

					e.printStackTrace();

				} catch (Exception e) {

					netError();

					e.printStackTrace();

				}



			}

		};

		requestThread = new Thread(task);

		requestThread.start();

	}



	/**

	 * 网络连接超时

	 * 

	 * @param text

	 * @param stringListener

	 */

	protected void timeOut(final String text,

			final RequestStringListener stringListener) {

		sendEmptyMessage(REQUEST_TIMEOUT);

		Looper.prepare();

		post(new Complete() {



			@Override

			public void run() {

				super.run();

				new AlertDialog.Builder(activity)

						.setTitle("网络连接超时")

						.setNegativeButton("取消", null)

						.setPositiveButton("重连",

								new DialogInterface.OnClickListener() {



									@Override

									public void onClick(DialogInterface dialog,

											int which) {

										showLog("重连");

										postRequest(text, stringListener);

									}

								}).show();

			}

		});



	}



	/**

	 * 网络连接错误或返回数据为空

	 * 

	 */

	protected void netError() {

		sendEmptyMessage(REQUEST_ERROR);

		Looper.prepare();

		post(new Complete() {



			@Override

			public void run() {

				super.run();

				if (!isNetworkConnect()) {

					whetherOpenNet();

				} else {

					Toast.makeText(getActivity(), "网络连接失败,请稍后重试",

							Toast.LENGTH_LONG).show();

				}

			}

		});

	}



	/**

	 * 发送post上传文件,获取字符串结果

	 * 

	 * @param isLoadCache

	 *            true为加载缓存,false为不加载缓存

	 */

	public String postStringResult() throws IOException, JSONException {

		showLog("path is " + path);

		showLog("post is " + postParams());

		HttpURLConnection conn = getConn(path, "POST");

		// 配置post请求的参数

		DataOutputStream outputStream = new DataOutputStream(

				conn.getOutputStream());

		outputStream.writeBytes(postParams());

		outputStream.flush();

		outputStream.close();



		if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {

			String data = formatStreamToString(conn);

			showLog("result is " + data);

			return data;

		}

		return null;

	}



	/**

	 * 根据url获取网络链接

	 * 

	 * @param path

	 * @param requestType

	 *            请求方式,post或者get

	 * @return

	 * @throws IOException

	 */

	private HttpURLConnection getConn(String path, String requestType)

			throws IOException {

		URL url = new URL(path);

		HttpURLConnection conn = (HttpURLConnection) url.openConnection();

		conn.setDoOutput(true);

		conn.setDoInput(true);

		conn.setRequestMethod(requestType);

		conn.setConnectTimeout(TIME_OUT);

		conn.setReadTimeout(TIME_OUT);

		conn.connect();

		return conn;

	}



	/**

	 * 将网络连接中的输入流转换成string字符串

	 * 

	 * @param conn

	 * @return

	 * @throws IOException

	 */

	private String formatStreamToString(HttpURLConnection conn)

			throws IOException {

		StringBuffer out = new StringBuffer();

		BufferedReader input = new BufferedReader(new InputStreamReader(

				conn.getInputStream()));

		String line = null;

		while ((line = input.readLine()) != null) {

			out.append(line);

		}

		input.close();

		return out.toString();

	}



	class Complete implements Runnable {

		@Override

		public void run() {

			if (pd != null) {

				pd.cancel();

			}

			requestThread.interrupt();

		}

	}



	/**

	 * 判断网络连接

	 */

	private boolean isNetworkConnect() {

		ConnectivityManager cm = (ConnectivityManager) activity

				.getSystemService(Context.CONNECTIVITY_SERVICE);

		cm.getActiveNetworkInfo();

		if (cm.getActiveNetworkInfo() != null) {

			return cm.getActiveNetworkInfo().isAvailable();

		}

		return false;

	}



	/**

	 * 打开网络对话框

	 */

	private void whetherOpenNet() {

		if (dialog != null) {

			dialog.cancel();

			dialog = null;

		}

		AlertDialog.Builder builder = new AlertDialog.Builder(activity);

		builder.setTitle("网络木有连接");

		builder.setMessage("是否打开网络连接");

		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {



			@Override

			public void onClick(DialogInterface dialog, int which) {

				activity.startActivityForResult(new Intent(

						Settings.ACTION_WIRELESS_SETTINGS), OPEN_NETWORK);

			}

		});

		builder.setNegativeButton("取消", null);

		dialog = builder.create();

		dialog.show();

	}



	/**

	 * 打印日志

	 * 

	 * @param log

	 */

	private void showLog(String log) {

		Log.d("example", log);

	}



	/**

	 * 获取当前NetApi绑定的activity

	 * 

	 * @return

	 */

	public Activity getActivity() {

		return this.activity;

	}



	/**

	 * 请求string的监听

	 */

	public interface RequestStringListener {

		/** 返回字符串 */

		public void onComplete(String result);

	}

}

你可能感兴趣的:(andriod)