zoukankan      html  css  js  c++  java
  • 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);
    	}
    }
  • 相关阅读:
    java学习笔记(三)
    JAVA 学习笔记(2)
    java学习笔记
    第二次作业完成情况
    第一次作业完成情况
    使用MarkDown标记语言发博客
    《Java高级程序设计》第一周作业
    纪逝去的毕业后的两年时光
    #这是来联系Markdown语法的
    CodeFirst初体验——问题三
  • 原文地址:https://www.cnblogs.com/oldfeel/p/3391881.html
Copyright © 2011-2022 走看看