网络图片查看器
2015-06-19 21:07
603 查看
如何使用安卓程序实现图片的异步图片加载,网络上传,网络查看。本届需要涉及到官员桌处理机制的问题,请参考 /article/6130863.html
1:下面是该程序的效果图:
在文本框中输入图片的路径,点击浏览按钮的同时,将会在上方的ImageView中显示出来该图片。
想要实现上面的程序,需要在按钮的点击事件中,在MainActivity的初始代码:
但是当在4.0以下的模拟器上运行会出现一些错误,
对于这个错误的出现:
一:什么是ANR
ANR:Application Not Responding,即应用无响应
二:ANR的类型
ANR一般有三种类型:
1:KeyDispatchTimeout(5 seconds) --主要类型
按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds)
BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) --小概率类型
Service在特定的时间内无法处理完成
三:KeyDispatchTimeout
Akey or touch event was not dispatched within the specified time(按键或触摸事件在特定时间内无响应)
具体的超时时间的定义在framework下的
ActivityManagerService.java
//How long we wait until we timeout on key dispatching.
staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000
四:为什么会超时呢?
超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成
五:如何避免KeyDispatchTimeout
1:UI线程尽量只做跟UI相关的工作
2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
3:尽量用Handler来处理UIthread和别的thread之间的交互
六:UI线程
说了那么多的UI线程,那么哪些属于UI线程呢?
UI线程主要包括如下:
Activity:onCreate(), onResume(), onDestroy(), onKeyDown(),
onClick(),etc
AsyncTask:
onPreExecute(), onProgressUpdate(), onPostExecute(),
onCancel,etc
Mainthread
handler: handleMessage(), post*(runnable r), etc
所以,应该对该算法进行改进,这就引入了线程的概念,关于线程,在ASP.NET或者java中应该都有详细解释。下面不再进行详细赘余。
什么是进程?
当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。
而一个进程又是由多个线程所组成的。
什么是线程?
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
什么是多线程?
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
多线程的好处:
可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。
多线程的不利方面:
线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
多线程需要协调和管理,所以需要CPU时间跟踪线程;
线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
线程太多会导致控制太复杂,最终可能造成很多Bug。
改进后的程序:(采用的是匿名内部类的方法)
页面布局activity_mian.xml:
关于异步加载图片,大概相同。
此处需要定义一个异步任务类,AsyncpicTask并让其继承AsyncTask。其主要的代码如下:
并修改MainActivity的代码:
对于布局等方面,这里没有进行阐述。实现的功能就是,在页面布局中添加按钮,ImageView控件,当点击异步下载图片的时候,便可以打开该图片,进行下载。
有关网络图片查看器的代码下载:https://github.com/xuyinghuicherish/InternetImageView
1:下面是该程序的效果图:
在文本框中输入图片的路径,点击浏览按钮的同时,将会在上方的ImageView中显示出来该图片。
想要实现上面的程序,需要在按钮的点击事件中,在MainActivity的初始代码:
public void viewImage(View view) { String path=etImageUrl.getText().toString();//把图片路径转换成字符串 if(TextUtils.isEmpty(path)) { /* * question:对于一个UI界面中,当判断用户是否输入用户名或密码时,我们常用TextUtils.isEmpty()方法来判断;但有时也可以用这个equals()方法,都可以来判断EditText中是否为空,但有时很纠结,不知道这两种方法中哪个比较好?为什么?*/ answer:仔细读官方的API: Returns true if the string is null or 0-length. 9 因为你从EditText返回的是一个变量。如果这个变量本身为null值,那么你掉它的equals方法是要报错的。但是如果你调用TextUtils.isEmpty() 把这个变量作为参数传进去。 10 只要这个参数为空或者为"",都会返回真。所以,用官方给的更加严谨。而且,也十分方便。因为你单独去判断你还不是要写一个if语句判断。返回的还是一个boolean值*/ Toast.makeText(this, R.string.NOnull, Toast.LENGTH_LONG).show();//如果输入路径为空,就弹出Toast }else{ //不为空,连接服务器,请求获得图片 try{ URL url=new URL(path); //发出http请求 HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("GET");//设置提交方式 //设置连接超时时间 httpURLConnection.setConnectTimeout(5000);//这时,我们设置为超时时间为5秒,如果5秒内不能连接就被认为是有错误发生. int responsecode=httpURLConnection.getResponseCode(); if(responsecode==200){ InputStream inputstream=httpURLConnection.getInputStream(); Bitmap bitmap=BitmapFactory.decodeStream(inputstream); ivImage.setImageBitmap(bitmap); }else{ Toast.makeText(this, R.string.error, Toast.LENGTH_LONG).show(); } }catch(MalformedURLException e){ e.printStackTrace(); }catch(IOException E){ E.printStackTrace(); } }
但是当在4.0以下的模拟器上运行会出现一些错误,
对于这个错误的出现:
一:什么是ANR
ANR:Application Not Responding,即应用无响应
二:ANR的类型
ANR一般有三种类型:
1:KeyDispatchTimeout(5 seconds) --主要类型
按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds)
BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) --小概率类型
Service在特定的时间内无法处理完成
三:KeyDispatchTimeout
Akey or touch event was not dispatched within the specified time(按键或触摸事件在特定时间内无响应)
具体的超时时间的定义在framework下的
ActivityManagerService.java
//How long we wait until we timeout on key dispatching.
staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000
四:为什么会超时呢?
超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成
五:如何避免KeyDispatchTimeout
1:UI线程尽量只做跟UI相关的工作
2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
3:尽量用Handler来处理UIthread和别的thread之间的交互
六:UI线程
说了那么多的UI线程,那么哪些属于UI线程呢?
UI线程主要包括如下:
Activity:onCreate(), onResume(), onDestroy(), onKeyDown(),
onClick(),etc
AsyncTask:
onPreExecute(), onProgressUpdate(), onPostExecute(),
onCancel,etc
Mainthread
handler: handleMessage(), post*(runnable r), etc
所以,应该对该算法进行改进,这就引入了线程的概念,关于线程,在ASP.NET或者java中应该都有详细解释。下面不再进行详细赘余。
什么是进程?
当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。
而一个进程又是由多个线程所组成的。
什么是线程?
线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
什么是多线程?
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
多线程的好处:
可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。
多线程的不利方面:
线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
多线程需要协调和管理,所以需要CPU时间跟踪线程;
线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
线程太多会导致控制太复杂,最终可能造成很多Bug。
改进后的程序:(采用的是匿名内部类的方法)
public void viewImage(View view){ final String imageUrl=etImageUrl.getText().toString(); if(TextUtils.isEmpty(imageUrl)){ Toast.makeText(this, "图片路径不能为空", Toast.LENGTH_LONG).show(); }else{ new Thread(){ public void run() { try { //在处理的过程中,必须进行异常处理 URL url=new URL(imageUrl); HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(5000); int responseCode=httpURLConnection.getResponseCode(); if(responseCode==200){ InputStream inputStream=httpURLConnection.getInputStream(); Bitmap bitmap=BitmapFactory.decodeStream(inputStream); Message message=new Message(); message.what=SHOWIMAGE; message.obj=bitmap; //ivImage.setImageBitmap(bitmap); handler.sendMessage(message); }else{ Toast.makeText(MainActivity.this, "显示图片失败", Toast.LENGTH_LONG).show(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }
页面布局activity_mian.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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ImageView android:id="@+id/ivImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" /> <EditText android:id="@+id/etImageUrl" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:hint="请输入图片的地址" android:text="@string/address"/> <Button android:id="@+id/btnView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/button_bg" android:onClick="viewImage" android:text="浏览" /> </LinearLayout>
关于异步加载图片,大概相同。
此处需要定义一个异步任务类,AsyncpicTask并让其继承AsyncTask。其主要的代码如下:
package com.jikexueyuan.hellonotes; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.crypto.spec.IvParameterSpec; import javax.net.ssl.HttpsURLConnection; import org.apache.http.entity.InputStreamEntity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.EventLogTags.Description; import android.widget.ImageView; public class AsyncPicTask extends AsyncTask<Object, Integer, Bitmap> { //定义Imageview属性 private ImageView mIvPicImageView; //定义后台执行方法 @Override protected Bitmap doInBackground(Object... params) { Bitmap bitmap=null; mIvPicImageView=(ImageView)params[0]; try { URL url=new URL((String)params[1]); //调用URL对象openConnection()方法创建URLConnection对象 try { HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //设置该urlConnection的doInput请求头字段的值 conn.setDoInput(true); //建立实际的连接 conn.connect(); //得到连接的字节流 InputStream inputStream=conn.getInputStream(); //解析图片 bitmap=BitmapFactory.decodeStream(inputStream); //关闭字节流对象 inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } return bitmap; } protected void onPostExecute(Bitmap result){ if(result!=null){ mIvPicImageView.setImageBitmap(result); } } }
并修改MainActivity的代码:
//异步上传图片 public class MainActivity extends Activity{ //private static final String URL="http://img5.duitang.com/uploads/item/201407/07/20140707212215_RHL8S.jpeg"; private static final String URL="http://pica.nipic.com/2008-07-01/200871134114809_2.jpg"; private Button mBtnPicTaskButton; private ImageView mIvPicImageView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //得到布局中的控件 findView(); //绑定控件事件 setListener(); } private void setListener() { //匿名内部类 mBtnPicTaskButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //定义异步任务,开启异步任务 AsyncPicTask picTask=new AsyncPicTask(); picTask.execute(mIvPicImageView,URL); } }); } private void findView() { // 绑定控件 mBtnPicTaskButton=(Button)findViewById(R.id.mBtnPicTaskButton); mIvPicImageView=(ImageView)findViewById(R.id.mIvPicImageView); }
对于布局等方面,这里没有进行阐述。实现的功能就是,在页面布局中添加按钮,ImageView控件,当点击异步下载图片的时候,便可以打开该图片,进行下载。
有关网络图片查看器的代码下载:https://github.com/xuyinghuicherish/InternetImageView
相关文章推荐
- 关于TCP保活功能及其应用
- 使用Apache commons-httpclient获取上传文件的进度
- BP神经网络
- 卷积神经网络
- httpd配置文件
- 能省则省:在ASP.NET Web API中通过HTTP Headers返回数据
- TCP/IP学习笔记(3)-----------TCP/IP协议详解
- HttpClient的认证(转载)
- 招对合适的网络营销推广人才
- TCP/IP学习笔记(2)----------IP协议与寻址
- 检测网络接口
- Nginx + Tomcat + HTTPS 配置原来不需要在 Tomcat 上启用 SSL 支持
- ios网络通信
- PowerShell统计本地的网络连接(CMD吐数据互访)
- C#网络编程(基本概念和操作) - Part.1
- java 获取https 网站内容(不需要导入证书)
- NAT穿透
- 思科路由器远程管理
- 深度神经网络结构以及Pre-Training的理解
- 写一个下载播放网络Gif的框架一:设计