前言
自己要做一个Android App,涉及到服务器端的用户数据管理,而网络上的的资源往往是只讲一个方面。所以自己每完成一段工作,会将开发过程记录下来,并供大家参考,相关文章放在专栏
【php + MySQL + Android】。
如果你遇到了什么问题,或者有好的建议,欢迎在评论区留言,或者私信我,大家一起交流。
独学而无友, 则孤陋而寡闻
因为项目要设计到网络传输,而一开始就用HTTPS 以及post方法,对小白来说跨度比较大,不能很好的理解原理,所以写了一个简单实例,用来理解网络传输的要点,为接下来的工作做准备。
功能描述
利用上一章节写的登陆界面,来获取服务器端的文本资源(自己没服务器也不要紧,用我的链接也是可以的,长久有效),并且显示出来。
点一下上面登录按钮,显示来自服务器的文本。UI界面在这篇文章里:
【php + MySQL + Android】Android登陆界面设计(1)_勇敢di牛牛的博客-CSDN博客
关键代码讲解
建立http连接的关键步骤整理:
把我们的文本转换成URL
String stringUrl = "http://nnggb.com/test/test.txt";URL myurl = new URL(stringUrl);
我们写出来的链接,是文本类型,所以首先我们要创建一个URL对象,把我们的url链接传进去,这样就可以进行后面的操作了(上面这个链接你们也可以用哦)创建http连接:
HttpURLConnection urlCon = (HttpURLConnection)myurl.openConnection();urlCon.setConnectTimeout(3000);
上面设置了一个三秒的超时。使用InputStreamReader,实现字节的输入流到字符的输入流的转换
InputStreamReader in = new InputStreamReader(urlCon.getInputStream());
BufferedReader buffer = new BufferedReader(in);
InputStreamReader:将一个字节的输入流转换为字符的输入流
OutputStreamWriter:将一个字符的输出流转换为字节的输出流
作用:提供字节流与字符流之间的转换解码:字节、字节数组 --->字符数组、字符串 看不懂的转换为看的懂的
编码:字符数组、字符串 ---> 字节、字节数组 看的懂的转换为看不懂的
关闭连接和读写操作
in.close();buffer.close();urlCon.disconnect();
创建新的线程,去执行我们的网络访问与数据读写。
new Thread(new Runnable(){
public void run(){
try {
URL myurl = new URL(stringUrl);
HttpURLConnection urlCon = (HttpURLConnection)myurl.openConnection();
urlCon.setConnectTimeout(3000);
InputStreamReader in = new InputStreamReader(urlCon.getInputStream());
BufferedReader buffer = new BufferedReader(in);
String inputLine = null;
StringBuffer pageBuffer = new StringBuffer();
(pageBuffer.toString().getBytes(StandardCharsets.UTF_8));
txt = buffer.readLine();
//txt = txt.substring(0,txt.length());
mHander.sendEmptyMessage(0);
in.close();
buffer.close();
urlCon.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
mHander.sendEmptyMessage(1);
} catch (IOException e) {
mHander.sendEmptyMessage(1);
e.printStackTrace();
}
}
}).start();
}
像这种网络请求和文件读写的操作放在主线程会影响我们的主交互的性能效果,是不被允许的,所以要新开一个线程。
new Thread(new Runnable())
这里实际上是通过实现Runnable接口的run方法去创建多线程。并new了一个线程对象。 ***别忘记后面的start()方法**
主线程接收新线程的消息
private static final int SUCCESS = 0;
private static final int FAILURE = 1; //
private String txt;
String stringUrl = "http://nnggb.com/test/test.txt";
private Handler mHander = new Handler(Looper.getMainLooper()) {
@SuppressLint("SetTextI18n")
public void handleMessage(Message msg) {
switch(msg.what){
case SUCCESS:
edt_user.setText(txt);
break;
case FAILURE:
edt_user.setText("download fail");
break;
}
}
};
这里进行处理消息操作。 当前线程如果是主线程的话,使用
Handler handler = new Handler();
不是主线程的话,
Handler handler = new Handler(Looper.getMainLooper());
我们新开的进程会发一个消息出来,这个函数就是去处理发给我们的消息;
Looper.getMainLooper()就是放在主线程去执行。
private static final int SUCCESS = 0;
private static final int FAILURE = 1; //
final是java关键字,被final修饰的变量值无法改变,代表“终态”的意思,这里是静态,我们后面要不停的去判断新线程是否有消息过来,这种写法不会去不断地开辟新的内存,大大提高我们的性能与流畅度。
捕获异常
这里的两种异常都需要捕获,要不然是会报错的,这里捕获的信息,会在我们run的时候显示出来,方便我们调试。
代码(注意第一行的名字)
package com.example.testapp;
import static java.util.Base64.*;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Editable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class MainActivity extends Activity {
Button btn_login;
Button btn_register;
EditText edt_user;
EditText edt_password;
URL url1;
private Handler handler;
private String result = "";
private EditText content;
private static final int SUCCESS = 0;
private static final int FAILURE = 1; //
private String txt;
String stringUrl = "http://nnggb.com/test/test.txt";
private Handler mHander = new Handler(Looper.getMainLooper()) {
@SuppressLint("SetTextI18n")
public void handleMessage(Message msg) {
switch(msg.what){
case SUCCESS:
edt_user.setText(txt);
break;
case FAILURE:
edt_user.setText("download fail");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_login = findViewById(R.id.bt_login);
btn_register = findViewById(R.id.bt_register);
edt_user = findViewById(R.id.edt_user);
edt_password =findViewById(R.id.edt_password);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GetURLResources();
}
});
}
public void GetURLResources(){
new Thread(new Runnable(){
public void run(){
try {
URL myurl = new URL(stringUrl);
HttpURLConnection urlCon = (HttpURLConnection)myurl.openConnection();
urlCon.setConnectTimeout(3000);
InputStreamReader in = new InputStreamReader(urlCon.getInputStream());
BufferedReader buffer = new BufferedReader(in);
String inputLine = null;
StringBuffer pageBuffer = new StringBuffer();
// while((inputLine = buffer.readLine()) != null){
// pageBuffer.append(inputLine +"\n");
// };
//设置字符编码格式
//txt = new String (pageBuffer.toString().getBytes(StandardCharsets.UTF_8));
txt = buffer.readLine();
//txt = txt.substring(0,txt.length());
mHander.sendEmptyMessage(0);
in.close();
buffer.close();
urlCon.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
mHander.sendEmptyMessage(1);
} catch (IOException e) {
mHander.sendEmptyMessage(1);
e.printStackTrace();
}
}
}).start();
}
}
可能出现的错误:
- 连接网络
- 添加如下权限在Manifest文件里:
其他问题评论区留言或私信
版权归原作者 勇敢di牛牛 所有, 如有侵权,请联系我们删除。