基于IntentService的Android登录完整示例

1.后台使用简单的servlet,支持GET或POST。这个servlet最终返回给前台一个字符串flag,值是true或false,表示登录是否成功。

/**
* Copyright(C) 2014
*
* 模块名称:     
* 子模块名称:   
*
* 备注:
*
* 修改历史:
* 2014-1-26	1.0		[email protected]		新建
*/
package cn.edu.hbcit.minicms.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import cn.edu.hbcit.minicms.dao.Login;
import cn.edu.hbcit.minicms.util.PasswordEncodeBean;

/**
 * 登录控制类
 * 简要说明:
 * @author [email protected]
 * @version 1.00  2014-1-26下午07:21:13	新建
 */

public class LoginServlet extends HttpServlet {
	protected final static Logger log = Logger.getLogger(LoginServlet.class.getName());

	/**
	 * Constructor of the object.
	 */
	public LoginServlet() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	/**
	 * The doGet method of the servlet. <br>
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		this.doPost(request, response);
	}

	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		Boolean flag = false;
		Login login = new Login();
		PasswordEncodeBean encode = new PasswordEncodeBean();
		String userName = request.getParameter("un");
		String password = request.getParameter("pw");
		flag = login.login(userName, encode.MD5Encode(password));
		log.debug("登录结果是:" + flag);
		out.print(flag);
		out.flush();
		out.close();
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		// Put your code here
	}

}

2.在ADT中新建一个android工程,建立两个Activity,分别作为登录界面和登录成功界面。

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/mainContent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <EditText
        android:id="@+id/userName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" 
        android:inputType="text" />"


    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/myButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Submit" />

</LinearLayout>
activity_result.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ResultActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

3.HTTP的访问公共类,用于处理GET和POST请求

package edu.hbcit.testandroid.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.util.Log;

public class HttpUtil
{
	// 创建HttpClient对象
	public static HttpClient httpClient = new DefaultHttpClient();
	public static final String BASE_URL = 
		"http://192.168.1.101:8080/server/"; //注意不要用127.0.0.1
	/**
	 * 
	 * @param url 发送请求的URL
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String getRequest(String url)
		throws Exception
	{
		// 创建HttpGet对象。
		HttpGet get = new HttpGet(url);
		// 发送GET请求
		HttpResponse httpResponse = httpClient.execute(get);
		// 如果服务器成功地返回响应
		if (httpResponse.getStatusLine()
			.getStatusCode() == 200){
			// 获取服务器响应字符串
			String result = EntityUtils.toString(httpResponse.getEntity());
			return result;
		}else{
			Log.d("服务器响应代码", (new Integer(httpResponse.getStatusLine().getStatusCode())).toString());
			return null;
		}
		
	}

	/**
	 * 
	 * @param url 发送请求的URL
	 * @param params 请求参数
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String postRequest(String url, Map<String ,String> rawParams)throws Exception{
		// 创建HttpPost对象。
		HttpPost post = new HttpPost(url);
		// 如果传递参数个数比较多的话可以对传递的参数进行封装
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		for(String key : rawParams.keySet()){
			//封装请求参数
			params.add(new BasicNameValuePair(key , rawParams.get(key)));
		}
		// 设置请求参数
		post.setEntity(new UrlEncodedFormEntity(params, "gbk"));
		// 发送POST请求
		HttpResponse httpResponse = httpClient.execute(post);
		// 如果服务器成功地返回响应
		if (httpResponse.getStatusLine().getStatusCode() == 200){
			// 获取服务器响应字符串
			String result = EntityUtils.toString(httpResponse.getEntity());
			return result;
		}
		return null;
	}
}

4.IntentService服务,用于在后台以队列方式处理耗时操作。

package edu.hbcit.testandroid.service;

import java.util.HashMap;

import edu.hbcit.testandroid.util.HttpUtil;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class ConnectService extends IntentService {
	private static final String ACTION_RECV_MSG = "edu.hbcit.testandroid.intent.action.RECEIVE_MESSAGE";

	public ConnectService() {
		super("TestIntentService");
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		/**
		 * 经测试,IntentService里面是可以进行耗时的操作的 
		 * IntentService使用队列的方式将请求的Intent加入队列,
		 * 然后开启一个worker thread(线程)来处理队列中的Intent  
		 * 对于异步的startService请求,IntentService会处理完成一个之后再处理第二个  
		 */
		Boolean flag = false;
		//通过intent获取主线程传来的用户名和密码字符串
		String username = intent.getStringExtra("username");
		String password = intent.getStringExtra("password");
		flag = doLogin(username, password);
		Log.d("登录结果", flag.toString());
		
		Intent broadcastIntent = new Intent();
		broadcastIntent.setAction(ACTION_RECV_MSG);  
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);  
		broadcastIntent.putExtra("result", flag.toString());
		sendBroadcast(broadcastIntent);
	}
	
	 // 定义发送请求的方法
 	private Boolean doLogin(String username, String password)
 	{
 		String strFlag = "";
 		// 使用Map封装请求参数
 		HashMap<String, String> map = new HashMap<String, String>();
 		map.put("un", username);
 		map.put("pw", password);
 		// 定义发送请求的URL
// 		String url = HttpUtil.BASE_URL + "LoginServlet?un=" + username + "&pw=" + password;  //GET方式
 		String url = HttpUtil.BASE_URL + "LoginServlet"; //POST方式
 		Log.d("url", url);
 		Log.d("username", username);
 		Log.d("password", password);
 		try {
			// 发送请求
			strFlag = HttpUtil.postRequest(url, map);  //POST方式
// 			strFlag = HttpUtil.getRequest(url);  //GET方式
			Log.d("服务器返回值", strFlag);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 		
 		if(strFlag.trim().equals("true")){
 			return true;
 		}else{
 			return false;
 		}
 		
 	}

}

5.在AndroidManifest.xml中注册IntentService。注意uses-permission节点,为程序开启访问网络的权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="edu.hbcit.testandroid"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="14" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="edu.hbcit.testandroid.activity.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="edu.hbcit.testandroid.activity.ResultActivity"
            android:label="@string/title_activity_result" >
        </activity>
        <service android:name="edu.hbcit.testandroid.service.ConnectService">
        </service>
    </application>

</manifest>

6.重头戏Activity登场——需要注意的几个要点

  1. 按钮监听事件中,使用Intent将要传递的值传给service。有点类似于Java Web中的session。
  2. 接收广播类中,同样使用Intent将要传递的值传给下一个Activity。
  3. 在onCreate()中,动态注册接收广播类的实例receiver。
  4. 在接收广播类中,不要使用完毕后忘记注销接收器,否则会报一个Are you missing a call to unregisterReceiver()? 的异常。

package edu.hbcit.testandroid.activity;

import java.util.HashMap;

import edu.hbcit.testandroid.R;
import edu.hbcit.testandroid.R.id;
import edu.hbcit.testandroid.R.layout;
import edu.hbcit.testandroid.R.menu;
import edu.hbcit.testandroid.service.ConnectService;
import edu.hbcit.testandroid.util.DialogUtil;
import edu.hbcit.testandroid.util.HttpUtil;
import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

	private static final String ACTION_RECV_MSG = "edu.hbcit.testandroid.intent.action.RECEIVE_MESSAGE";
	private MessageReceiver receiver ;
	EditText et_username ;
	EditText et_password;
	
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取文本view
        TextView tv = (TextView)findViewById(R.id.mainContent);
        //获取输入框
        et_username = (EditText)findViewById(R.id.userName);
        et_password = (EditText)findViewById(R.id.password);
        //获取按钮
        Button submit = (Button)findViewById(R.id.myButton);
        tv.setText("这是Hello World登录示例");
        //http://192.168.1.101:8080/server/LoginServlet?un=aaa&pw=123456
        //为按钮绑定事件监听器
        submit.setOnClickListener(new OnClickListener(){
        	public void onClick(View v){
        		if (validate()){
        			// 如果登录成功
        			Intent msgIntent = new Intent(MainActivity.this, ConnectService.class);
        			msgIntent.putExtra("username", et_username.getText().toString().trim());
        			msgIntent.putExtra("password", et_password.getText().toString().trim());
        			startService(msgIntent);
        		}
        	}
        });
        
        //动态注册receiver  
        IntentFilter filter = new IntentFilter(ACTION_RECV_MSG);  
        filter.addCategory(Intent.CATEGORY_DEFAULT);  
        receiver = new MessageReceiver();  
        registerReceiver(receiver, filter);  
    }
	
	// 对用户输入的用户名、密码进行校验
	 	private boolean validate()
	 	{
	 		String username = et_username.getText().toString().trim();
	 		if (username.equals(""))
	 		{
	 			DialogUtil.showDialog(this, "用户名是必填项!", false);
	 			return false;
	 		}
	 		String pwd = et_password.getText().toString().trim();
	 		if (pwd.equals(""))
	 		{
	 			DialogUtil.showDialog(this, "密码是必填项!", false);
	 			return false;
	 		}
	 		return true;
	 	}
    
	//接收广播类  
    public class MessageReceiver extends BroadcastReceiver {  
        @Override  
        public void onReceive(Context context, Intent intent) {  
           String message = intent.getStringExtra("result");  
           Log.d("MessageReceiver", message);
        // 如果登录成功
			if (message.equals("true")){
				// 启动Main Activity
				Intent nextIntent = new Intent(MainActivity.this, ResultActivity.class);
				startActivity(nextIntent);
				// 结束该Activity
				finish();
				//注销广播接收器
				context.unregisterReceiver(this);
			}else{
				DialogUtil.showDialog(MainActivity.this, "用户名称或者密码错误,请重新输入!", false);
			}
			
        }  
    }  
    
}

运行效果:

1.登录界面

基于IntentService的Android登录完整示例_第1张图片

2.登录失败界面

基于IntentService的Android登录完整示例_第2张图片

3.登录成功界面


小李专栏原创文章,转自需注明出处【http://blog.csdn.net/softwave】。

你可能感兴趣的:(基于IntentService的Android登录完整示例)