用于获取网络连接的接口,我们常用它的实现类HttpURLConnection设置网络连接信息。
//通过一个URL对象
URL url = new URL(path);
//获取openConnection,用于对连接进行设置
HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
//设置请求方式
openConnection.setRequestMethod("GET");
//设置超时时间
openConnection.setConnectTimeout(5000);
进行网络操作不可以在主线程中,所以需要另外开一个线程。
操作UI相关只能在主线程中,所以需要在子线程中调用runOnUiThread操作前面板控件,或者使用消息机制。
1、发送请求
(1)创建一个URL对象
(2)设置请求头信息
2、服务器返回数据
(1)判断状态码:200 ok,404 没有找到资源、503、509 服务器端错误
(2)解析服务器返回的二进制数据,解析成一个图片
(3)把图片显示在TextView上
public void click(View v)
{
new Thread(new Runnable() {
@Override
public void run() {
try {
//获取路径
path = et_path.getText().toString().trim();
URL url = new URL(path);
HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
openConnection.setRequestMethod("GET");
openConnection.setConnectTimeout(5000);
//获取返回码
int responseCode = openConnection.getResponseCode();
if(responseCode == 200) //返回成功
{
InputStream in = openConnection.getInputStream();
final String str = StreamUtils.ReadStream(in);
System.out.println(str+"+++++++++++");
//将显示信息放到主线程
runOnUiThread(new Runnable() {
@Override
public void run() {
//设置显示控件显示源码信息
tv_content.setText(str);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//用于从网络中读取数据
public static String ReadStream(InputStream in) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len = 0;
while((len=in.read(buf)) != -1)
{
baos.write(buf, 0, len);
}
return baos.toString();
}
消息机制可以用来进行主线程与子线程间的通信,由于子线程不能操作显示控件,我们可以把一些信息放到消息中,主线程收到消息后对控件进行操作
在主线程创建的时候注册一个消息handler,重写handleMessage方法,对消息的内容进行处理。
主线程
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
uper.handleMessage(msg);
//这里是收到消息,获取消息的内容
tv_content.setText((String)msg.obj);
}
};
子线程
//获取一个msg
Message msg = Message.obtain();
//设置msg携带的信息
msg.obj = str;
//发送这个信息给主线程中注册的 Handler(){
handler.sendMessage(msg);
BitmapFactory.decodeStream(in); 将流转换为bitmap
msg.what = 1; 设置msg中携带的数字消息
1、创建URL,打开一个HTTP的连接;
2、设置请求头信息:GET(GET、POST)
3、接收服务器端返回的响应数据,响应码:200 ok,404没有找到资源 ,503服务器端内部错误
4、把接收的二进制数据转换成图片
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
final ImageView iv_img = (ImageView) findViewById(R.id.iv_img);
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//获取msg 并判断msg的类型
int statu = msg.what;
if(statu == 1)
{
//在主线设置显示bitmap
iv_img.setImageBitmap(bitmap);
}
}
};
}
public void click(View v)
{
new Thread(new Runnable() {
@Override
public void run() {
try {
//获取路径
path = et_path.getText().toString().trim();
URL url = new URL(path);
HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
openConnection.setRequestMethod("GET");
openConnection.setConnectTimeout(5000);
//获取返回码
int responseCode = openConnection.getResponseCode();
if(responseCode == 200) //返回成功
{
//获取网络上响应的数据流
InputStream in = openConnection.getInputStream();
//使用BitmapFactory将数据流转换为bitmap
bitmap = BitmapFactory.decodeStream(in);
//设置msg的信息
Message msg = Message.obtain();
msg.what = 1;
//发送msg给主线程
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
new Thread(){public void run() {
//Android系统 底层 有一个审计机制 在开发中 都使用 Handler 审计机制启动需要时间,启动后如果在子线程中直接操作显示控件,就会报
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//这个方法最终都会在ui线程中执行
runOnUiThread( new Runnable() {
public void run() {
tv.setText("哈哈 我更新了ui");
}
});
};}.start();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//5秒钟之后执行 run方法
tv.setText("haha");
}
}, 5000);
//回顾Timer的使用
Timer timer = new Timer(); //创建一个定时器
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("haha");
}
};
//5 秒钟后 执行 run方法
//5秒后 执行run方法 在每隔2秒钟在执行一次 run方法
timer.schedule(task, 5000,2000);
1.功能需要使用上一个条目的知识,在一定的时间后调用某个指定的函数
2.需要知道如何切换到另外一个页面
1.class MainActivity2 extends Activity //建立一个类,继承Activity
2.onCreate 中设置要加载的页面布局文件setContentView(R.layout.activity_main2);
3.在清单文件中配置布局文件
<activity android:name="com.example.myweixinstartup.MainActivity2"></activity>
4.Intent intent = new Intent(MainActivity.this, MainActivity2.class); //用Intent加载这个新的页面
5.startActivity(intent);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
startActivity(intent);
}
}, 3000);
1.创建的时候,需要连接服务器,获取新闻信息(XML文件)
2.解析XML文件,封装相关条目(Item),存入一个List返回该List
3.将条目依次显示到ListView中
*图片资源在XML中存放一个URL地址,可以使用SmartImageView(开源项目)作为图片的类替代ImageView,SmartImageView中提供了直接从URL中获取图片资源的方法。
先考虑两个问题
1.List文件如何将条目显示到ListView中?
在getView方法中通过positon作为List的索引。
2.ListView在哪里设置显示?
注意,使用网络操作,获取xml文件,是在一个子线程中进行的。这样,如果我们把显示xml信息的方法直接放在主线程中,那么就可能在没有获取List信息的情况下
就执行了显示ListView的方法。所以,应该把显示操作放在
public class MainActivity extends Activity {
private List<NewsItem> itemLists;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.lv);
init();
}
public void init()
{
final String path="http://192.168.19.114/news/news.xml";
new Thread(){
public void run() {
try {
URL url = new URL(path);
HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
openConnection.setReadTimeout(5000);
openConnection.setRequestMethod("POST");
int type = openConnection.getResponseCode();
if(type == 200)
{
InputStream is = openConnection.getInputStream();
itemLists = XMLUtiles.getItems(is);
}
//由于xml中的信息是在子线程中获取的,如果显示直接放到主线程,则不能保证在显示时已经获取到xml的数据
runOnUiThread(new Runnable() {
@Override
public void run() {
listView.setAdapter(new MyAdaptor());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
class MyAdaptor extends BaseAdapter {
@Override
public int getCount() {
return itemLists.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if(convertView == null){
view = View.inflate(getApplicationContext(), R.layout.item, null);
}else{
view = convertView;
}
//使用position参数作为List的索引
NewsItem newsItem = itemLists.get(position);
TextView tv_title = (TextView)view.findViewById(R.id.tv_title);
TextView tv_content = (TextView)view.findViewById(R.id.tv_content);
TextView tv_type = (TextView)view.findViewById(R.id.tv_type);
SmartImageView tv_image = (SmartImageView) view.findViewById(R.id.tv_image);
tv_title.setText(newsItem.getTitle());
tv_content.setText(newsItem.getDescription());
tv_type.setText(newsItem.getType());
tv_image.setImageUrl(newsItem.getImage());
return view;
}
}
}
使用get方法提交数据
public void click(View v)
{
final String username = et_username.getText().toString().trim();
final String password = et_password.getText().toString().trim();
new Thread(){
public void run() {
//将数据直接写到url中
String pathString = "http://192.168.19.114/web/LoginServlet?username="+username+"&password="+password;
try {
URL url = new URL(pathString);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
if(code == 200)
{
InputStream in = conn.getInputStream();
String retStr = StreamUtils.ReadStream(in);
showToast(retStr);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
使用post方法提交数据
public void click1(View v)
{
final String username = et_username.getText().toString().trim();
final String password = et_password.getText().toString().trim();
new Thread(){
public void run() {
String pathString = "http://192.168.19.114/web/LoginServlet";
try {
//创建URL对象
URL url = new URL(pathString);
//打开一个URL连接
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置请求方式 POST字符串需要大写
conn.setRequestMethod("POST");
//设置超时时间
conn.setConnectTimeout(5000);
//数据为键值对
String data = "username="+username+"&password="+password;
//设置请求头信息,下面的用于post请求
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", data.length()+"");
// 设置一个标记 允许像服务器输出
conn.setDoOutput(true);
//把数据写到输出流中进行输出操作
conn.getOutputStream().write(data.getBytes());
int code = conn.getResponseCode();
if(code == 200)
{
InputStream in = conn.getInputStream();
String retStr = StreamUtils.ReadStream(in);
showToast(retStr);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
弹出土司,由于在网络子线程中,所以可以将土司封装一下
public void showToast(final String str)
{
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}
});
}
读取网络流工具包
public class StreamUtils {
public static String ReadStream(InputStream in) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len = 0;
while((len=in.read(buf)) != -1)
{
baos.write(buf, 0, len);
}
return baos.toString("gbk");
}
}