今天了解了一下 android 客户端与服务端是怎样交互的,发现其实跟 web 有点类似吧,然后网上找了大神的登陆示例,是基于 IntentService 的
1. 后台使用简单的 servlet,支持 GET 或 POST。这个 servlet 最终返回给前台一个字符串 flag,值是 true 或 false,表示登录是否成功。
servlet 使用之前需要配置,主义 servlet 的 servlet-name 要和 servlet-mapping 的 servlet-name 一致,否则找不到路径
我是在 myEclipse 上创建的一个 web service 项目,然后部署到 tomcat 服务器上以便 android 客户端访问
1
2
3
4
5
6
7
8
|
<servlet>
<servlet-name>helloWorld</servlet-name>
<servlet-
class
>com.zhongzhong.wap.action.HelloServlet</servlet-
class
>
</servlet>
<servlet-mapping>
<servlet-name>helloWorld</servlet-name>
<url-pattern>/queryOrder</url-pattern>
</servlet-mapping>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
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
javax.servlet.http.HttpSession;
import
com.zhongzhong.wap.bean.UserBean;
public
class
HelloServlet
extends
HttpServlet {
@Override
protected
void
doGet(HttpServletRequest req, HttpServletResponse resp)
throws
ServletException, IOException {
doPost(req, resp);
}
@Override
protected
void
doPost(HttpServletRequest req, HttpServletResponse resp)
throws
ServletException, IOException {
resp.setContentType(text/html);
PrintWriter out = resp.getWriter();
Boolean flag =
false
;
String userName = req.getParameter(un);
String password = req.getParameter(pw);
if
(userName.equals(htp)&&password.equals(
123
))
{
flag =
true
;
}
else
flag =
false
;
System.out.println(userName:+userName+ password:+password);
out.print(flag);
out.flush();
out.close();
}
}
|
2. 然后我是在安卓的 ADT 上创建一个安卓项目,建立两个 Activity,分别作为登录界面和登录成功界面。
1
2
3
4
5
6
7
8
9
10
|
<relativelayout android:layout_height=
"match_parent"
android:layout_width=
"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=
".MainActivity"
xmlns:android=
"https://schemas.android.com/apk/res/android"
xmlns:tools=
"https://schemas.android.com/tools"
>
<textview android:id=
"@+id/textView1"
android:layout_alignparenttop=
"true"
android:layout_centerhorizontal=
"true"
android:layout_height=
"wrap_content"
android:layout_margintop=
"40dp"
android:layout_width=
"wrap_content"
android:text=
"HelloWorld登陆示例"
>
<edittext android:ems=
"10"
android:hint=
"请输入账号"
android:id=
"@+id/et_user"
android:layout_below=
"@+id/textView1"
android:layout_centerhorizontal=
"true"
android:layout_height=
"wrap_content"
android:layout_margintop=
"33dp"
android:layout_width=
"wrap_content"
>
<requestfocus>
</requestfocus></edittext>
<edittext android:ems=
"10"
android:hint=
"请输入密码"
android:id=
"@+id/et_psw"
android:inputtype=
"textPassword"
android:layout_below=
"@+id/et_user"
android:layout_centerhorizontal=
"true"
android:layout_height=
"wrap_content"
android:layout_margintop=
"40dp"
android:layout_width=
"wrap_content"
><button android:id=
"@+id/btn_login"
android:layout_below=
"@+id/et_psw"
android:layout_centerhorizontal=
"true"
android:layout_height=
"wrap_content"
android:layout_margintop=
"37dp"
android:layout_width=
"wrap_content"
android:text=
"登陆"
></button></edittext></textview></relativelayout>
|
1
2
3
4
5
|
<relativelayout android:layout_height=
"match_parent"
android:layout_width=
"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=
".NaviActivity"
xmlns:android=
"https://schemas.android.com/apk/res/android"
xmlns:tools=
"https://schemas.android.com/tools"
>
<textview android:layout_alignparenttop=
"true"
android:layout_centerhorizontal=
"true"
android:layout_height=
"wrap_content"
android:layout_margintop=
"46dp"
android:layout_width=
"wrap_content"
android:text=
"登陆成功"
>
</textview></relativelayout>
|
3.HTTP 的访问公共类,用于处理 GET 和 POST 请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package
com.example.logindemo;
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.content.Entity;
import
android.util.Log;
public
class
HttpUtil {
// 创建HttpClient对象
public
static
HttpClient httpClient =
new
DefaultHttpClient();
public
static
final
String BASE_URL = https:
//192.168.3.14:8090/HelloWord/;
/**
*
* @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, UTF-
8
));
// 发送POST请求
HttpResponse httpResponse = httpClient.execute(post);
// 如果服务器成功地返回响应
if
(httpResponse.getStatusLine().getStatusCode() ==
200
) {
// 获取服务器响应字符串
String result = EntityUtils.toString(httpResponse.getEntity());
return
result;
}
return
null
;
}
}
</namevaluepair></namevaluepair></string,>
|
4.IntentService 服务,用于在后台以队列方式处理耗时操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package
com.example.logindemo;
import
java.util.HashMap;
import
android.app.IntentService;
import
android.content.Intent;
import
android.util.Log;
public
class
ConnectService
extends
IntentService {
private
static
final
String ACTION_RECV_MSG = com.example.logindemo.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 + queryOrder?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
;
}
}
}
</string,></string,>
|
5。在 AndroidManifest.xml 中注册 IntentService。注意 uses-permission 节点,为程序开启访问网络的权限。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<!--?xml version=
1.0
encoding=utf-
8
?-->
<manifest android:versioncode=
"1"
android:versionname=
"1.0"
package
=
"com.example.logindemo"
xmlns:android=
"https://schemas.android.com/apk/res/android"
>
<uses-sdk android:minsdkversion=
"8"
android:targetsdkversion=
"18"
>
<uses-permission android:name=
"android.permission.INTERNET"
>
<intent-filter>
<category android:name=
"android.intent.category.LAUNCHER"
>
</category></action></intent-filter>
</activity>
</activity>
<service android:name=
"com.example.logindemo.ConnectService"
>
</service>
</application>
</uses-permission></uses-sdk></manifest>
|
6. 登陆界面处理,注意
- 按钮监听事件中,使用 Intent 将要传递的值传给 service。接收广播类中,同样使用 Intent 将要传递的值传给下一个 Activity。在 onCreate() 中,动态注册接收广播类的实例 receiver。在接收广播类中,不要使用完毕后忘记注销接收器,否则会报一个 Are you missing a call to unregisterReceiver()? 的异常。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104package
com.example.logindemo;
import
android.os.Bundle;
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.Toast;
public
class
MainActivity
extends
Activity {
private
static
final
String ACTION_RECV_MSG = com.example.logindemo.action.RECEIVE_MESSAGE;
private
Button loginBtn;
private
EditText et_username;
private
EditText et_password;
private
String userName;
private
String passWord;
private
MessageReceiver receiver ;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//动态注册receiver
IntentFilter filter =
new
IntentFilter(ACTION_RECV_MSG);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver =
new
MessageReceiver();
registerReceiver(receiver, filter);
}
private
void
initView() {
// TODO Auto-generated method stub
et_username = (EditText)findViewById(R.id.et_user);
et_password =( EditText)findViewById(R.id.et_psw);
loginBtn = (Button)findViewById(R.id.btn_login);
loginBtn.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
if
(matchLoginMsg())
{
// 如果校验成功
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);
}
}
});
}
protected
boolean
matchLoginMsg() {
// TODO Auto-generated method stub
userName = et_username.getText().toString().trim();
passWord = et_password.getText().toString().trim();
if
(userName.equals())
{
Toast.makeText(MainActivity.
this
, 账号不能为空,Toast.LENGTH_SHORT).show();
return
false
;
}
if
(passWord.equals())
{
Toast.makeText(MainActivity.
this
, 密码不能为空,Toast.LENGTH_SHORT).show();
return
false
;
}
return
true
;
}
//接收广播类
public
class
MessageReceiver
extends
BroadcastReceiver {
@Override
public
void
onReceive(Context context, Intent intent) {
String message = intent.getStringExtra(result);
Log.i(MessageReceiver, message);
// 如果登录成功
if
(message.equals(
true
)){
// 启动Main Activity
Intent nextIntent =
new
Intent(MainActivity.
this
, NaviActivity.
class
);
startActivity(nextIntent);
// 结束该Activity
finish();
//注销广播接收器
context.unregisterReceiver(
this
);
}
else
{
Toast.makeText(MainActivity.
this
, 用户名或密码错误,请重新输入!,Toast.LENGTH_SHORT).show();
}
}
}
@Override
public
boolean
onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return
true
;
}
}
运行截图: