遇到的问题如下:
- java.lang.NullPointerException: Attempt to invoke virtual method ‘void java.io.BufferedReader.close()’ on a null object reference
- android.os.NetworkOnMainThreadException异常
- android java.net.UnknownHostException: Unable to resolve host “…”: No address associated 错误
- Genymotion虚拟器重的android6.0模拟器连不上网(没完全解决)
今天花了将近8个小时学习android文件下载知识,先是看视频学习,然后自己动手敲代码学习,我是跟着大神的视频一个字一个字敲的,然而当我敲完,运行的时候突然遇到了这个问题:
FATAL EXCEPTION: main
Process: com.example.sun.downloadfilestudy, PID: 19432
java.lang.NullPointerException: Attempt to invoke virtual method ‘void java.io.BufferedReader.close()’ on a null object reference
at com.example.sun.utils.HttpDownloadUtil
at android.view.View.performClick(View.java:5198)
at android.view.View
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616
源代码是如下:
public String downFile(String urlStr){
StringBuffer stringBuffer = new StringBuffer();
BufferedReader bufferedReader = null;
URL url = null;
String line = null;
try {
//创建一个URL对象
url = new URL(urlStr);
//根据URL对象创建一个Http连接
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
//使用IO读取下载的文件数据
InputStream inputStream = urlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while((line = bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally{
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return stringBuffer.toString();
}
然后我就去百度“ java.lang.NullPointerException: Attempt to invoke virtual method ‘void java.io.BufferedReader.close()’ on a null object reference”
结果出来:
一大片英文的,虽然我英文还不错,但是我还是不想看,我就不信那么多中国人就我一个遇到这个问题,哈哈!于是我就自己分析试试,我猜测是“bufferedReader = new BufferedReader(new InputStreamReader(inputStream));”这句中的bufferedReader 为空,那么也就意味着inputStream为空,也就可以推导出“ InputStream inputStream = urlConnection.getInputStream();”这句中的 urlConnection.getInputStream()为空,而我调试的过程中发现urlConnection这个不为空,于是我就猜测getInputStream()这个出错了 ,于是我去百度“android getInputStream()出错”结果我看到一个解释是没有配置权限:
然后我看了下我的AndroidManifast.xml文件,我记得我配过,果然有,我就呵呵了!然后我问我老师,老师说把这个:
<!-- 使用网络功能所需权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
都加上,于是我就加上了,还是同样的错,〒〒。后来我还怀疑我代码中的url不对,于是我到处去网上找可以下载的文件的ip地址,结果找了好久都没找到,全是下载的文件保存在哪,哎〒〒。
于是我就暂时放下这个问题,一直到下午老师说在他开发的网站上放一个test.txt文件让我试试,我试了之后非常生气,还是一样的错,我(╯▔皿▔)╯生气了!!!!!!于是我发誓不把这个问题搞定我就不姓孙!!!!。
我去百度换了一个问法:”Android 文件下载失败“,结果出来的真的让我喜出望外啊,就有一个大神是这样说的:需要注意的是在Android3.0之前的Android平台上可以直接Activity所在的线程中访问网络,下载网络上的文件。但是这样的话,如果下载的文件较大,或者网速比较慢的情况下,Activity界面就会处于无法及时响应用户操作的状态。Android3.0中如果在Activity所在的线程访问网络,调试执行时会出现异常信息:“android.os.NetworkOnMainThreadException”,无法获取有效的HttpURLConnection对象。所以我们需要把访问网络,下载文件的操作放在另外的线程中。
还有一个大神是这样说的:**
遇到的问题1. java.lang.NullPointerException报错,2.android.os.NetworkOnMainThreadException异常
原因:urlCon.getInputStream()执行的时候出错导致,得不到InputStream。这个异常大概意思是在主线程访问网络时出的异常。 造成这样的错误原因是代码不符合Android规范,Android在4.0之前的版本支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。 **
总之就一句话:”现在已经不能在当前线程中下载文件了,需要开一个单独的线程来下载文件“!
原来的代码是这样的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadText = (Button) findViewById(R.id.downText);
downloadText.setOnClickListener(new ButtonDownloadText());
}
class ButtonDownloadText implements View.OnClickListener {
@Override
public void onClick(View v) {
String url = "http://xssl.yzu.edu.cn/android/test.txt";
System.out.println(httpDownloadUtil.downFile(url));
}
}
单独开线程的代码是这样的:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttontxt = (Button) findViewById(R.id.buttontxt);
//为buttontxt添加单击事件监听器
buttontxt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建一个匿名线程用于下载文件
new Thread() {
public void run() {
HttpDownloader httpDownloader = new HttpDownloader();
//调用httpDownloader对象的重载方法download下载txt文件
String txt = httpDownloader.download("http://xssl.yzu.edu.cn/android/test.txt ");
System.out.println(txt);
}
}.start();
}
});
于是我就改了代码,本来以为大功告成了,没想到又遇到一个问题:
“Unable to resolve host “…”: No address associated …”我的想法就是连接不了某个主机,我猜测是没有连接网络,于是我就去百度,有个大神是这样说的:
我在android开发的时候经常会遇到这个错误,一般来说,造成这种错误的最普遍情况有两种:
1.android设备网络连接没打开,例如3G网络和WIFI网络
所以,如果遇到这种错误时,请先查看网络是否已正常连接.
2.Manifest文件没有标明网络访问权限
如果确认网络已经正常连接并且还是出这种错误的话,那么请看下你的Manifest文件是否标明应用需要网络访问权限,如果没标明的话,也访问不了网络,也会造成这种情况的.
//网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
我第二个已经确认过了,那只有第一个原因了,但是想想我使用Genymotion虚拟器的,不是用真机测试,可能Genymotion真的没有联网,我打开模拟的浏览器输入www.baidu.com真的打不开,于是我就去找Genymotion联网的方法,
这个家伙和我遇到同样的问题了,我看他的设置再看了我的设置都是和网上别人说的一样,结果我们都还是连接不了网络,我想当时他肯定和我一样郁闷,不过幸运的是他问题下面有个大神给了提示:
也就是说一般来说按照这个设置就可以连上网了,不过在android 6.0上面,你还需要手动点击wifi模块,点击连接wifi,就会自动连接了。于是我打开我Genymotion中的android6.0模拟器,手动连接wifi,结果一直连接不上,太让我郁闷了,配置都对,就是连接不上,结果还给卡死了,于是我强制关闭模拟器,启动了android5.0的模拟器真的就自动连上网了,在模拟器中打开浏览器输入www.baidu.com可以出来网页了,于是我在Android Studio中重新将程序运行在android5.0模拟器上真的成功了!
感动到哭( ▼-▼ ),被我自己不放弃的精神感动哭了!于是记录下这个不容易,记录下解决方法,记录下自己的慢慢成长,明天继续加油!
最后附上几个大神的解决方案链接: