首页 > 代码库 > 05_android入门_GET方式实现登陆(在控件上显示服务端返回的内容)

05_android入门_GET方式实现登陆(在控件上显示服务端返回的内容)

当点击登陆之后,怎么把服务器端返回的数据,写到指定的控件上尼?,在android怎么实现尼?下面我们通过具体的代码进行分析和实现,希望能对你,在学习android知识上有所帮助。

下面通过代码说明:

package www.csdn.net.lesson03;


import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;


import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


public class LoginActivity extends Activity {
// 声明控件对象
private EditText et_name, et_pass;
// 声明显示返回数据库的控件对象
private TextView tv_result;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置显示的视图
setContentView(R.layout.activity_login);
// 通过 findViewById(id)方法获取用户名的控件对象
et_name = (EditText) findViewById(R.id.et_name);
// 通过 findViewById(id)方法获取用户密码的控件对象
et_pass = (EditText) findViewById(R.id.et_pass);


// 通过 findViewById(id)方法获取显示返回数据的控件对象
tv_result = (TextView) findViewById(R.id.tv_result);



}


/**
* 通过android:onClick="login"指定的方法 , 要求这个方法中接受你点击控件对象的参数v

* @param v
*/
public void login(View v) {
// 获取点击控件的id
int id = v.getId();
// 根据id进行判断进行怎么样的处理
switch (id) {
// 登陆事件的处理
case R.id.btn_login:
// 获取用户名
final String userName = et_name.getText().toString();
// 获取用户密码
final String userPass = et_pass.getText().toString();
if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPass)) {
Toast.makeText(this, "用户名或者密码不能为空", Toast.LENGTH_LONG).show();
} else {
System.out
.println("----------------------发送请求到服务器----------------------");
// 访问网络 (需要一个网络的权限) <uses-permission
// android:name="android.permission.INTERNET"/>
// 访问网络(耗时的操作) 避免阻塞主线程(UI) 需要开启新的子线程来处理
new Thread() {
public void run() {
// 调用loginByGet方法
loginByGet(userName, userPass);
};
}.start();

}
break;
default:
break;
}

}


/**
* 通过GET方式发送的请求

* @param userName
* @param userPass
*/
public void loginByGet(String userName, String userPass) {


try {
// 设置请求的地址 通过URLEncoder.encode(String s, String enc)
// 使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式
String spec = "http://172.16.237.200:8080/video/login.do?username="
+ URLEncoder.encode(userName, "UTF-8") + "&userpass="
+ URLEncoder.encode(userPass, "UTF-8");
// 根据地址创建URL对象(网络访问的url)
URL url = new URL(spec);
// url.openConnection()打开网络链接
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");// 设置请求的方式
urlConnection.setReadTimeout(5000);// 设置超时的时间
urlConnection.setConnectTimeout(5000);// 设置链接超时的时间
// 设置请求的头
urlConnection
.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");
// 获取响应的状态码 404 200 505 302
if (urlConnection.getResponseCode() == 200) {
// 获取响应的输入流对象
InputStream is = urlConnection.getInputStream();


// 创建字节输出流对象
ByteArrayOutputStream os = new ByteArrayOutputStream();
// 定义读取的长度
int len = 0;
// 定义缓冲区
byte buffer[] = new byte[1024];
// 按照缓冲区的大小,循环读取
while ((len = is.read(buffer)) != -1) {
// 根据读取的长度写入到os对象中
os.write(buffer, 0, len);
}
// 释放资源
is.close();
os.close();
// 返回字符串
String result = new String(os.toByteArray());
System.out.println("***************" + result+ "******************");


// 在这里把返回的数据写在控件上 会出现什么情况尼
tv_result.setText(result);

} else {
System.out.println("------------------链接失败-----------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

通过添加红色的代码进行实现,会发现出现如下bug:

05-24 06:38:37.987: W/System.err(1170): android.view.ViewRootImpl$CalledFromWrongThreadException:
 Only the original thread that created a view hierarchy can touch its views.
05-24 06:38:37.997: W/System.err(1170): 	
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
05-24 06:38:37.997: W/System.err(1170): 	
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
05-24 06:38:38.007: W/System.err(1170): 	
at android.view.View.requestLayout(View.java:16431)
05-24 06:38:38.007: W/System.err(1170): 	
at android.view.View.requestLayout(View.java:16431)
05-24 06:38:38.007: W/System.err(1170): 	
at android.view.View.requestLayout(View.java:16431)
05-24 06:38:38.007: W/System.err(1170): 	
at android.view.View.requestLayout(View.java:16431)
05-24 06:38:38.007: W/System.err(1170): 	
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
05-24 06:38:38.007: W/System.err(1170): 
at android.view.View.requestLayout(View.java:16431)
05-24 06:38:38.007: W/System.err(1170): 	
at android.widget.TextView.checkForRelayout(TextView.java:6600)
05-24 06:38:38.007: W/System.err(1170): 	
at android.widget.TextView.setText(TextView.java:3813)
05-24 06:38:38.007: W/System.err(1170): 	
at android.widget.TextView.setText(TextView.java:3671)
05-24 06:38:38.017: W/System.err(1170): 	
at android.widget.TextView.setText(TextView.java:3646)
05-24 06:38:38.017: W/System.err(1170): 	
at www.csdn.net.lesson03.LoginActivity.loginByGet(LoginActivity.java:134)
05-24 06:38:38.027: W/System.err(1170): 	
at www.csdn.net.lesson03.LoginActivity$1.run(LoginActivity.java:67)

错误的原因是:

只有原来的线程创建的视图层次可以触摸它的控件. 所以只有在主线程中,才能够设置返回数据控件的内容。

那么怎么实现效果,我们可以使用Activity中给我们提供的runOnUiThread(action);的方法实现,把我们要进行设置返回数据控件的内容放在此方法中即可。具体的部分代码如下:

// 返回字符串
				final String result = new String(os.toByteArray());
				System.out.println("***************" + result
						+ "******************");

				LoginActivity.this.runOnUiThread(new Runnable() { //才用此方法进行修改主线程中的UI控件内容
					@Override
					public void run() {
						// 在这里把返回的数据写在控件上 会出现什么情况尼
						tv_result.setText(result);
					}
				});
				

测试效果如下:

 

以上代码仅供参考学习,如有问题请留言