标签:android开发
从网络上获取数据: 文本、图片、音乐、视频。
步骤:
1、创建URL对象,打开一个HTTP类型的连接:
2、设置请求方式GET、POST,连接的超时时间等请求参数:
3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
4、把二进制流的响应数据转换成需要的数据类型:
模版代码:
// 1、创建URL对象,打开一个HTTP类型的连接:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
conn.setRequestMethod("GET");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
Bitmap bm = BitmapFactory.decodeStream(is);
//在imageview上显示一张图片
iv.setImageBitmap(bm);
}
android.os.NetworkOnMainThreadException:网络在主线程的异常;
activity中的oncreate、单击事件的响应方法都是运行在主线程上的;
Android4.0开始,google为了让UI界面运行的更加流畅,强制要求在主线程不能有访问网
络的操作,这样就可以避免了再主线程中因为访问网络时间太长导致主界面卡死等现象的发生。
Only the original thread that created a view hierarchy can touch its views.只有创建视图的那个线程才能修改视图。
只有(主线程、UI线程)创建UI界面的那个线程才能修改UI界面。子线程不能直接修改UI界面。
使用Handler修改UI界面的步骤:
1、在主线程中创建handler的成员变量
2、在子线程中得到handler的引用,调用handler的sendMessage,给主线程发送一个消息,我要修改U‘界面了
3、主线程授权handler,hanlder修改UI界面
代码:
package com.itheima.viewpic;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_path;
private ImageView iv;
//1、在主线程中创建handler的成员变量
private Handler handler = new Handler(){
// 3、主线程授权handler,hanlder修改UI界面
/**
* 接收并处理消息
* msg 在子线程传递过来的消息对象
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//修改U界面
Bitmap bm = (Bitmap) msg.obj;
iv.setImageBitmap(bm);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
iv = (ImageView) findViewById(R.id.iv);
}
public void get(View view) {
final String path = et_path.getText().toString().trim();
if (TextUtils.isEmpty(path)) {
Toast.makeText(this, "图片的网络地址不能为空", 0).show();
return;
} else {
new Thread(){
public void run() {
// 访问网络,从网络上获取图片的数据,并且现在imageview
try {
// 1、创建URL对象,打开一个HTTP类型的连接:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
conn.setRequestMethod("GET");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
Bitmap bm = BitmapFactory.decodeStream(is);
//在imageview上显示一张图片
// iv.setImageBitmap(bm);
// 2、在子线程中得到handler的引用,调用handler的sendMessage,给主线程发送一个消息,我要修改U‘界面了
//创建一个消息对象,消息盒子
Message msg = new Message();
msg.obj = bm;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
}
Handler的工作机制(Handler、Message、Looper三者之间的关系):
前提知识:所有使用UI界面的操作系统,后台都在运行着一个死循环。它在不停地监听和接
收用户发出的指令,一旦接收到指令就马上执行。
当前应用程序一启动的时候,系统就会给应用程序提供Looper(轮询器)。子线程在需要修改
UI界面的时候,给handler发送一个消息(Message),handler接收到消息后会把消息放到Looper内部维护的消息队列中,Looper内部维护的死循环会不停的从消息队列中取消息,一旦取到消息就会发送给handler,然后handler再去修改UI界面。
代码:
package com.itheima.htmlview;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.itheima.htmlview.utils.StreamTools;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_path;
private TextView tv_result;
//1、在主线程中创建handler的成员变量
private Handler handler = new Handler(){
// 3、主线程授权handler,hanlder修改UI界面
/**
* 接收并处理消息
* msg 在子线程传递过来的消息对象
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//修改U界面
String result = (String) msg.obj;
tv_result.setText(result);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path = (EditText) findViewById(R.id.et_path);
tv_result = (TextView) findViewById(R.id.tv_result);
}
public void getHTML(View view){
final String path = et_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this, "页面的路径不能为空", 0).show();
return;
}else{
//访问网络获取页面的数据
new Thread(){
public void run() {
// 访问网络,从网络上获取图片的数据,并且现在imageview
try {
// 1、创建URL对象,打开一个HTTP类型的连接:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
conn.setRequestMethod("GET");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
String result = StreamTools.readStreamToStr(is);
//在imageview上显示一张图片
// iv.setImageBitmap(bm);
// 2、在子线程中得到handler的引用,调用handler的sendMessage,给主线程发送一个消息,我要修改UI界面了
//创建一个消息对象,消息盒子
Message msg = new Message();
msg.obj = result;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
}
使用runOnUiThread方法修改UI界面:
//运行在主线程,内部使用线程合并技术join
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
步骤:
1、设计UI界面:在布局文件中添加listview控件、添加item的布局文件:
2、访问网络,得到服务器端返回的二进制输入流:
3、解析xml格式的数据:
4、填充listview:
代码:
布局文件:
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"
tools:context=".MainActivity" >
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lv" />
</LinearLayout>
item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="80dip"
android:layout_height="80dip"
android:src="@drawable/ic_launcher"
android:id="@+id/iv_image"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_title"
android:text="标题标题标题标题标题标题标题标题标题标题标题标题标题标题"
android:singleLine="true"
android:layout_toRightOf="@id/iv_image"
android:textSize="16sp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_desc"
android:layout_below="@id/tv_title"
android:layout_toRightOf="@id/iv_image"
android:text="描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述描述"
android:maxLines="3"
android:textSize="12sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_type"
android:text="跟帖"
android:layout_alignParentRight="true"
android:layout_below="@id/tv_desc"
android:textSize="10sp"
/>
</RelativeLayout>
MainActivity.java:
package com.itheima.newsclient;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.itheima.newsclient.domain.NewsItem;
import com.itheima.newsclient.service.NewsItemParseService;
public class MainActivity extends Activity {
private ListView lv;
private List<NewsItem> list;
private static final String path = "http://192.168.1.254:8080/news.xml";
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
//填充listview
lv.setAdapter(new MyAdapter());
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
//给listview填充数据
fillData();
}
private void fillData() {
//访问网络,解析xml个数据
new Thread(){
public void run() {
// 访问网络,从网络上获取图片的数据,并且现在imageview
try {
// 1、创建URL对象,打开一个HTTP类型的连接:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
conn.setRequestMethod("GET");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
list = NewsItemParseService.parseNewsItems(is);
//在imageview上显示一张图片
// iv.setImageBitmap(bm);
// 2、在子线程中得到handler的引用,调用handler的sendMessage,给主线程发送一个消息,我要修改UI界面了
// 创建一个消息对象,消息盒子
Message msg = new Message();
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return list.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view =null;
if(convertView != null){
view = convertView;
}else{
view = View.inflate(MainActivity.this, R.layout.item, null);
}
//给布局文件中的控件填充数据
ImageView iv_image = (ImageView) view.findViewById(R.id.iv_image);
TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
TextView tv_desc = (TextView) view.findViewById(R.id.tv_desc);
TextView tv_type = (TextView) view.findViewById(R.id.tv_type);
NewsItem item = list.get(position);
tv_title.setText(item.getTitle());
tv_desc.setText(item.getDescription());
if("1".equals(item.getType())){
tv_type.setText(item.getComment()+"跟贴");
tv_type.setTextColor(Color.BLACK);
}else if("2".equals(item.getType())){
tv_type.setText("视频");
tv_type.setTextColor(Color.BLUE);
}else if("3".equals(item.getType())){
tv_type.setText("专题");
tv_type.setTextColor(Color.RED);
}
return view;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
}
需要注意的地方:
1、给smartimageview添加构造方法:
2、把图片显示在自己身上:
代码:
package com.itheima.smartimageview;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.ImageView;
public class SmartImageView extends ImageView {
public SmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SmartImageView(Context context) {
super(context);
}
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
Bitmap bm = (Bitmap) msg.obj;
//把图片显示在自己身上
SmartImageView.this.setImageBitmap(bm);
};
};
public void setImageUrl(final String path){
new Thread(){
public void run() {
// 访问网络,从网络上获取图片的数据,并且现在imageview
try {
// 1、创建URL对象,打开一个HTTP类型的连接:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
conn.setRequestMethod("GET");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
Bitmap bm = BitmapFactory.decodeStream(is);
Message msg = Message.obtain();
msg.obj = bm;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
1、登陆
2、上传文件
使用GET方式向服务器端提交数据时,是把参数组拼了url地址的后面:
示例:
http://192.168.1.254:8080/web/servlet/LoginServlet?username=12343erwewr&password=sdfds
与get方式的不同点:
1、URL地址不一样:
2、请求方式是POST、添加了Content-Type、Content-Length;
3、以输出流的形式向服务器端提交数据:
模版代码:
package com.itheima.qqloginbyget;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int SUCCESS = 0;
protected static final int FAILED = 1;
private EditText et_username;
private EditText et_pwd;
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
String result = (String) msg.obj;
Toast.makeText(MainActivity.this, result, 0).show();
break;
case FAILED:
Toast.makeText(MainActivity.this, "网络异常,获取数据失败", 0).show();
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_username = (EditText) findViewById(R.id.et_username);
et_pwd = (EditText) findViewById(R.id.et_pwd);
}
public void login(View view){
final String username = et_username.getText().toString().trim();
final String pwd = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd) ){
Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
return;
}else{
//访问网络,提交数据给服务器端
new Thread(){
public void run() {
// 访问网络,从网络上获取图片的数据,并且现在imageview
try {
String path="http://192.168.1.254:8080/web/servlet/LoginServlet";
// 1、创建URL对象,打开一个HTTP类型的连接:
String data = "username="+username+"&password="+pwd;
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// 2、设置请求方式GET、POST,连接的超时时间等请求参数:
// 请求方式是POST、添加了Content-Type、Content-Length;
conn.setRequestMethod("POST");// 默认是GET方式,要大写
conn.setReadTimeout(3000);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", data.length()+"");
// 设置是否允许向服务器端写数据
conn.setDoOutput(true);
// 向服务器端写数据(提交数据)
conn.getOutputStream().write(data.getBytes());
// conn.setRequestProperty("Accept-Language", "zh-CN");
// 3、得到服务器端返回的响应数据(以二进制流的形式返回响应数据),判断响应码是不是200请求成功、404找不到资源、503服务器端内部错误:
//判断响应码是不是200
int code = conn.getResponseCode();
if(200 == code){
InputStream is = conn.getInputStream();
// 4、把二进制流的响应数据转换成需要的数据类型:
String result = StreamTools.readStreamToStr(is);
Message msg = Message.obtain();
//定义一个消息码,用来区分消息从什么地方发送的
msg.what = SUCCESS;
msg.obj = result;
handler.sendMessage(msg);
}
} catch (Exception e) {
Message msg = Message.obtain();
//定义一个消息码,用来区分消息从什么地方发送的
msg.what = FAILED;
msg.obj = "网络异常,获取数据失败";
handler.sendMessage(msg);
e.printStackTrace();
}
};
}.start();
}
}
}
补间动画:图片的透明度、旋转、平移、缩放等变化的过程就补间动画;
透明度:alpha
旋转:rotate
平移:translate
缩放:scale
代码:
package com.itheima.tweens;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
public void alpha(View view) {
// fromAlpha开始透明度的值 0表示完全透明,1.0表示完全不透明
// toAlpha 结束透明度0表示完全透明,1.0表示完全不透明
AlphaAnimation aa = new AlphaAnimation(0, 1.0f);
// 设置动画播放时间
aa.setDuration(3000);
// 设置动画重复播放次数
aa.setRepeatCount(2);
// 设置动画重复播放的模式
aa.setRepeatMode(AlphaAnimation.REVERSE);
// 在imageview上播放动画
iv.startAnimation(aa);
}
public void rotate(View view) {
// fromAlpha开始透明度的值 0表示完全透明,1.0表示完全不透明
// toAlpha 结束透明度0表示完全透明,1.0表示完全不透明
RotateAnimation ra = new RotateAnimation(0, 360,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放时间
ra.setDuration(3000);
// 设置动画重复播放次数
ra.setRepeatCount(2);
// 设置动画重复播放的模式
ra.setRepeatMode(RotateAnimation.REVERSE);
// 在imageview上播放动画
iv.startAnimation(ra);
}
public void trans(View view) {
TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 200);
// 设置动画播放时间
ta.setDuration(3000);
// 设置动画重复播放次数
ta.setRepeatCount(2);
// 设置动画重复播放的模式
ta.setRepeatMode(TranslateAnimation.REVERSE);
// 在imageview上播放动画
iv.startAnimation(ta);
}
public void scale(View view) {
ScaleAnimation sa = new ScaleAnimation(0, 1.0f, 0, 1.0f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放时间
sa.setDuration(3000);
// 设置动画重复播放次数
sa.setRepeatCount(2);
// 设置动画重复播放的模式
sa.setRepeatMode(ScaleAnimation.REVERSE);
// 在imageview上播放动画
iv.startAnimation(sa);
}
public void set(View view) {
//shareInterpolator 是否共享插桶
AnimationSet set = new AnimationSet(false);
AlphaAnimation aa = new AlphaAnimation(0, 1.0f);
// 设置动画播放时间
aa.setDuration(3000);
// 设置动画重复播放次数
aa.setRepeatCount(2);
// 设置动画重复播放的模式
aa.setRepeatMode(AlphaAnimation.REVERSE);
set.addAnimation(aa);
RotateAnimation ra = new RotateAnimation(0, 360,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放时间
ra.setDuration(3000);
// 设置动画重复播放次数
ra.setRepeatCount(2);
// 设置动画重复播放的模式
ra.setRepeatMode(RotateAnimation.REVERSE);
set.addAnimation(ra);
TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 200);
// 设置动画播放时间
ta.setDuration(3000);
// 设置动画重复播放次数
ta.setRepeatCount(2);
// 设置动画重复播放的模式
ta.setRepeatMode(TranslateAnimation.REVERSE);
set.addAnimation(ta);
ScaleAnimation sa = new ScaleAnimation(0, 1.0f, 0, 1.0f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
// 设置动画播放时间
sa.setDuration(3000);
// 设置动画重复播放次数
sa.setRepeatCount(2);
// 设置动画重复播放的模式
sa.setRepeatMode(ScaleAnimation.REVERSE);
set.addAnimation(sa);
iv.startAnimation(set);
}
}
标签:android开发
原文地址:http://blog.csdn.net/faith_yee/article/details/44853175