day04 网络编程

1.写一个网络源码查看器

思路:

1.写布局 EditText Button TextView ok

2.找控件,设置点击事件 ok

3.在点击事件的onclick中,获取用户输入的url ok

4.访问url,获取源码 ********* 不ok

//4.1 创建一个URL对象;

URL url = new URL(url_str);

//4.2 通过url对象获取一个HttpUrlConnection对象

HttpURLConnection cn = (HttpURLConnection) url.openConnection();

//4.3 为HttpUrlConnection对象设置一些参数 . 如:网络请求方式 ,连接的超时时间

cn.setRequestMethod("GET");//设置网络的请求方式 GET ,POST一定 要大写

cn.setConnectTimeout(10*1000);//设置网络连接的超时时间

//4.4 获取网络的响应状态码

int code = cn.getResponseCode();//获取服务器的响应码

//4.5判断状态码是否是200,如果是200 获取流数据

if(code == 200){

InputStream inputStream = cn.getInputStream();//获取一个读取流读取服务器返回的数据

//4.6 将获取的流数据转换成字符串,就是我们所需的源码

String result = Utils.StreamToString(inputStream);

//5.将源码显示到TextView上

tv_source.setText(result);

}

5.将源码显示到TextView上

2.出现的问题

1.注意添加网络访问权限:

2.ANR: 多次点击按钮会出现application not response应用无响应的异常;

安卓规定耗时的操作(网络请求,大文件的拷贝,数据库的操作)需要放到子线程中执行,不能在主线程中执行.4.0以后android强制要求网络请求必须放到子线程中执行,android4.0之后会报错误:NetworkOnMainThreadException;

11-01 02:44:12.618: E/ActivityManager(858): ANR in com.itheima.sourcelook (com.itheima.sourcelook/.MainActivity)

3.NetworkOnMainThreadException 网络访问在主线程异常

11-01 02:47:40.231: W/System.err(1806): android.os.NetworkOnMainThreadException

4.当创建了子线程并将操作放入子线程之后会报CalledFromWrongThreadException 错误的线程调用异常 ,只有主线程才能够更新UI,子线程不能更新UI(改变控件的内容或样式)。

11-01 02:56:07.750: W/System.err(1947): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

结论:耗时的操作需要放到子线程中执行,不能在主线程中执行;只有主线程才能更新UI,子线程获取到数据不能直接更新UI.产生了矛盾。。如何解决? Handler

3.handler消息机制

思路:

1.在主线程创建一个Handler对象,成员变量。

new Handler()

2.重新handler对象的handlerMessage方法

new Handler(){

handlerMessage(Message msg){

}

}

3.在子线程中创建一个Message对象。

Message msg = new Message();

4.将子线程获取的结果绑定给Message对象

msg.obj = result;

5.子线程中使用主线程创建的handler将Message对象发送到主线程

handler.sendMessage(msg);

6.主线程中的handler对象的handlerMessage方法接受子线程发来的Message对象,可以获取Message对象中绑定的数据,做UI更新

new Handler(){

handlerMessage(Message msg){

String result = msg.obj;

textview.setText(result);

}

}

4.网络图片查看器

BitmapFactory 可以将各种各样的资源(文件,流,二进制数组)转换成一个Bitmap对象。

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

代码:

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//2.找控件,写点击事件

et_url = (EditText) findViewById(R.id.et_url);

img_pic = (ImageView) findViewById(R.id.img_pic);

findViewById(R.id.bt_getpic).setOnClickListener(this);

System.out.println("oncreate:"+Thread.currentThread().getName());

}

//☆☆☆☆☆  1.在主线程中创建一个Handler对象

privateHandler handler =newHandler(){

//☆☆☆☆☆  2.复写Handler对象的一个handlerMessage方法

publicvoidhandleMessage(android.os.Message msg) {

//☆☆☆☆☆  6.在主线程的handler对象中的handleMessage方法接受子线程发来的Message对象,并获取绑定的数据;那么主线程就可以更新UI了。

Bitmap bm  = (Bitmap) msg.obj;

// 当前线程为主线程,可以更新Ui

//5.将bitmap设置给Imageview做展示

img_pic.setImageBitmap(bm);

};

};

@Override

publicvoidonClick(View v) {

//创建一个子线程

newThread(newRunnable() {

@Override

publicvoidrun() {

System.out.println("runnable:"+Thread.currentThread().getName());

//3.在点击事件的onclick中,获取用户输入的url  ok

String url_str = et_url.getText().toString().trim();

try{

//4.访问url,获取源码              ********* 不ok

//4.1 创建一个URL对象;

URL url =newURL(url_str);

//4.2 通过url对象获取一个HttpUrlConnection对象

HttpURLConnection cn = (HttpURLConnection) url.openConnection();

//4.3  为HttpUrlConnection对象设置一些参数 .   如:网络请求方式 ,连接的超时时间

cn.setRequestMethod("GET");//设置网络的请求方式 GET ,POST一定 要大写

cn.setConnectTimeout(10*1000);//设置网络连接的超时时间

//4.4 获取网络的响应状态码

intcode = cn.getResponseCode();//获取服务器的响应码

//4.5判断状态码是否是200,如果是200 获取流数据

if(code == 200){

InputStream inputStream = cn.getInputStream();//获取一个读取流读取服务器返回的数据

//4.6 将获取的流数据转换成图片资源   Drawable Bitmap:位图

//使用BitmapFactory将各种资源(流,文件,二进制数组)转换成图片对象Bitmap

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

//☆☆☆☆☆  3.在子线程中创建一个Message对象

Message msg =newMessage();

//☆☆☆☆☆  4.将子线程中获取的数据绑定给Message对象

msg.obj = bitmap;

//☆☆☆☆☆  5.使用主线程中的handler对象将绑定数据的Message对象发送到主线程

handler.sendMessage(msg);

}

}catch(Exception e) {

e.printStackTrace();

}

}

}).start();

}

5.设计自己的SmartImageView控件(可以通过URI设置控件显示的图片)

思路:

1.通过httpurlconnection连接网络资源

2.通过bitmapfactory获得bitmap(factory可以通过流转换bitmap)

3.建立message

4.用handler传递message获得bitmap

5.在自己的控件中显示

注意:

自定义控件:

1.写一个类继承ImageView,写三个构造方法

2.写一个setImageUrl方法,请求url地址,获取图片流,转换成bitmap,设置给当前类的对象。

3.在布局文件中引用自定义的MySmartImageView ,注意,引用时,需要指定类的完整路径。

代码

publicclassMySmartImageViewextendsImageView{

Handlerhand=newHandler(){

publicvoidhandleMessage(Message msg) {

Bitmap img=(Bitmap) msg.obj;

//自定义控件标签要写全包名

//

//android:layout_height="68dp"

//android:layout_width="68dp"

//android:layout_margin="10dp"

//android:id="@+id/iv_view"

//android:src="@drawable/ic_launcher"/>

MySmartImageView.this.setImageBitmap(img);

};

};

//一定要复写3个方法,否则运行会报错

publicMySmartImageView(Context context, AttributeSet attrs,intdefStyle) {

super(context, attrs, defStyle);

//TODOAuto-generated constructor stub

}

publicMySmartImageView(Context context, AttributeSet attrs) {

super(context, attrs);

//TODOAuto-generated constructor stub

}

publicMySmartImageView(Context context) {

super(context);

//TODOAuto-generated constructor stub

}

publicvoidSetImageUrl(String url)

{

finalString url2=url;

newThread(newRunnable() {

@Override

publicvoidrun() {

try{

URL url1=newURL(url2);

HttpURLConnection con=(HttpURLConnection) url1.openConnection();

con.setReadTimeout(10000);

con.setRequestMethod("GET");

if(con.getResponseCode()==200)

{

InputStream in=con.getInputStream();

Bitmap img=BitmapFactory.decodeStream(in);

Message msg=newMessage();

msg.obj=img;

hand.sendMessage(msg);

}

}catch(MalformedURLException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

//TODOAuto-generated method stub

}

}).start();

}

}

6.常见消息处理API

1.子线程可以更新UI的情况

//面试:: 审计机制 ,在activity完全显示之后才会工作,才会检测是否在子线程中更新UI,显示之前更新UI审计机制不会工作。

// 还有一些情况可以在子线程更新Ui,如SurfaceView和与进度条相关的控件都可以在子线程更新UI。

代码:

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv_text= (TextView)findViewById(R.id.tv_text);

//SystemClock.sleep(5000);

newThread(newRunnable() {

publicvoidrun() {

SystemClock.sleep(5000);

tv_text.setText("我被更新了");

}

}).start();

}

2.runOnUiThread方法:无论当前线程是否是主线程,都会被在主线程中执行

//在activity中有一个runOnUIthread方法,UI线程就是主线程无论要运行的动作是否是主线程,都将会在主线程运行。

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

});

3.handler 的post方法

//使用handler 的post方法将一个动作发送到主线程去执行。 这个handler必须定义在主线程

handler.post(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

});

4.handler 的postDelaed方法,发送一个延迟的动作到主线程,特别适合做广告展示。

//delayMillis:延迟的时间

handler.postDelayed(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

}, 5000);

7.android的Json解析

1.android自带Json封装API

String result = Utils.StreamToString(inputStream);//获得一个Json字符串

//6.解析json字符串,封装到list中

JSONObject root_json = new JSONObject(result);//将一个json字符串转换成一个jsonObject

//根据json的key获取newss这个json数组

JSONArray jsonArray = root_json.getJSONArray("newss");

//遍历jsonArray获取一条条json数据

for (int i = 0; i < jsonArray.length(); i++) {

JSONObject newsJson = jsonArray.getJSONObject(i);//根据索引获取数组中的一个json对象

NewsBean bean = new NewsBean();

bean.id = newsJson.getInt("id");

bean.comment = newsJson.getInt("comment");

bean.type = newsJson.getInt("type");

bean.title =      newsJson.getString("title");

bean.des =      newsJson.getString("des");

bean.icon_url = newsJson.getString("icon_url");

bean.news_url = newsJson.getString("news_url");

bean.time = newsJson.getString("time");

arrayList.add(bean);

2.第三方工具包解析介绍(最好选择Gson)

1.、各个JSON技术的简介和优劣

1.json-lib

json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,

包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,

对于复杂类型的转换,json-lib对于json转换成bean还有缺陷,比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。

json-lib在功能和性能上面都不能满足现在互联网化的需求。

2.开源的Jackson

相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。

而且Jackson社区相对比较活跃,更新速度也比较快。

Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。

Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式

3.Google的Gson

Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,

但自从在2008年五月公开发布第一版后已被许多公司或用户应用。

Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。

而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。

类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。

Gson在功能上面无可挑剔,但是性能上面比FastJson有所差距。

4.阿里巴巴的FastJson

Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。

无依赖,不需要例外额外的jar,能够直接跑在JDK上。

FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。

FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。

综上4种Json技术的比较,在项目选型的时候可以使用Google的Gson和阿里巴巴的FastJson两种并行使用,

如果只是功能要求,没有性能要求,可以使用google的Gson,

如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean

Gson解析:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容