Exception(一)

1、android.os.NetworkOnMainThreadException异常问题

两种访问方法都出现这个异常(HttpClient+HttpGet+HttpResponse+HttpEntity|HttpURLConnection),均可以访问了,下面异常介绍和解决方法:

08-24 23:09:14.038:I/Choreographer(994): Skipped 56 frames! The application may be doing too much work on its main thread.

08-24 23:09:14.553:D/gralloc_goldfish(994): Emulator without GPU emulation detected.

08-24 23:09:18.384:D/AndroidRuntime(994): Shutting down VM

08-24 23:09:18.384: W/dalvikvm(994): threadid=1: thread exiting withuncaught exception (group=0x414c4700)

08-24 23:09:18.463: E/AndroidRuntime(994): FATAL EXCEPTION: main

08-24 23:09:18.463: E/AndroidRuntime(994):android.os.NetworkOnMainThreadException

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)

08-24 23:09:18.463:E/AndroidRuntime(994): atjava.net.InetAddress.lookupHostByName(InetAddress.java:385)

08-24 23:09:18.463:E/AndroidRuntime(994): atjava.net.InetAddress.getAllByNameImpl(InetAddress.java:236)

08-24 23:09:18.463:E/AndroidRuntime(994): atjava.net.InetAddress.getAllByName(InetAddress.java:214)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)

08-24 23:09:18.463:E/AndroidRuntime(994): atorg.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

08-24 23:09:18.463:E/AndroidRuntime(994): atinternet.Internet.getInfo(Internet.java:37)

08-24 23:09:18.463:E/AndroidRuntime(994): atcom.example.systemstudyandroid.MainActivity$3.onClick(MainActivity.java:114)

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.view.View.performClick(View.java:4240)

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.view.View$PerformClick.run(View.java:17721)

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.os.Handler.handleCallback(Handler.java:730)

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.os.Handler.dispatchMessage(Handler.java:92)

08-24 23:09:18.463:E/AndroidRuntime(994): atandroid.os.Looper.loop(Looper.java:137)

08-24 23:09:18.463:E/AndroidRuntime(994): at android.app.ActivityThread.main(ActivityThread.java:5103)

08-24 23:09:18.463:E/AndroidRuntime(994): atjava.lang.reflect.Method.invokeNative(Native Method)

08-24 23:09:18.463:E/AndroidRuntime(994): atjava.lang.reflect.Method.invoke(Method.java:525)

08-24 23:09:18.463:E/AndroidRuntime(994): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)

08-24 23:09:18.463:E/AndroidRuntime(994): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)

08-24 23:09:18.463:E/AndroidRuntime(994): atdalvik.system.NativeStart.main(Native Method)

08-24 23:09:22.133:I/Process(994): Sending signal. PID: 994 SIG: 9

/**

*Finally, I come into a android with internet;

*/

这个问题是由于线程引起的;刚开始程序跑起来的时候并没有出现什么异常-----因为此时并没有涉及网络操作;

当点击一个button后,系统出现above的错误,其中的android.os.NetworkOnMainThreadException异常;

自己的解决方法就是原来申请网络操作的地方,放在一个线程中操作,结果跑通了;

然后搜了一下网络上的解析:

android.os.NetworkOnMainThreadException

网上搜索后知道是因为版本问题,在4.0之后在主线程里面执行Http请求都会报这个错,也许是怕Http请求时间太长造成程序假死的情况吧。那么网上的朋友也给出了相应的解决方案,这叫上有政策下有对策:

一:在发起Http请求的Activity里面的onCreate函数里面添加如下代码:

//详见StrictMode文档
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());

如果正在做的项目不是Android 4.0的是看不到StrictMode类的。我也是用的网上给的com_weibo_android.jar。但是这个jar包下载下来的时候是2.3 的,要先转换成Android 4.0的项目,再在分享对应的ShareActivity的onCreate()函数中添加上面的两行代码。这样就不会报这个错误了。

二:使用Thread、Runnable、Handler这三个类:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.share_mblog_view);
    new Thread(runnable).start();
}
 
Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        Bundle data = msg.getData();
        String val = data.getString("value");
        Log.i("mylog","请求结果为-->" + val);
    }
}
 
 
Runnable runnable = new Runnable(){
    @Override
    public void run() {
        //
        // TODO: http request.
        //
        Message msg = new Message();
        Bundle data = new Bundle();
        data.putString("value","请求结果");
        msg.setData(data);
        handler.sendMessage(msg); }}
 

2、java.net.ProtocolException异常问题

java.net.ProtocolException: cannot write to a URLConnection if doOutput=false -call setDoOutput(true)

    atsun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source)

    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(UnknownSource)

    at http.HttpGetTest.httpGet(HttpGetTest.java:63)

    at http.HttpGetTest.main(HttpGetTest.java:29)

解决方法:

conn.setDoOutput(true);//conn is a case about HttpURLConnection

 

3、java.net.SocketTimeoutException异常问题

java.net.SocketTimeoutException: connect timed out

    at java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method)

    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)

    at java.net.AbstractPlainSocketImpl.connectToAddress(UnknownSource)

    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)

    at java.net.PlainSocketImpl.connect(Unknown Source)

    at java.net.SocksSocketImpl.connect(Unknown Source)

    at java.net.Socket.connect(Unknown Source)

    at sun.net.NetworkClient.doConnect(Unknown Source)

    at sun.net.www.http.HttpClient.openServer(Unknown Source)

    at sun.net.www.http.HttpClient.openServer(Unknown Source)

    at sun.net.www.http.HttpClient.<init>(Unknown Source)

    at sun.net.www.http.HttpClient.New(Unknown Source)

    at sun.net.www.http.HttpClient.New(Unknown Source)

    atsun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)atsun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)atsun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)atsun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)athttp.HttpGetTest.httpGet(HttpGetTest.java:60)at http.HttpGetTest.main(HttpGetTest.java:29)

解决方法:

Strings = newHttpGetTest().httpGet(3000,url1);

设置长一点的超时Timeout;

1000改成3000ms;

4、java.net.ProtocolException n异常问题

OutputStream与InputStream的顺序问题:

java.net.ProtocolException: Cannot write output after reading input.

    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(UnknownSource)

    atsun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)

    at http.HttpGetTest.httpGet(HttpGetTest.java:63)

    athttp.HttpGetTest.main(HttpGetTest.java:29)

解决方法:OutputStream是放在InputStream之前进行的操作,这也是由于访问Http的顺序决定的;

其中,getHeaderField()操作需要访问服务器,获得;

经过测试,该方法也是需要获得服务器返回值,也需要客户端的Input,可以删去或者将Output方法提前;

5、java.lang.ClassCastException异常问题

/*Integer cannot be cast to java.lang.String*/

Exception in thread"main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

    at http.UrlConnUtil.httpResponse(UrlConnUtil.java:107)

    at http.UrlConnUtil.get(UrlConnUtil.java:72)

    at http.UrlConnUtil.main(UrlConnUtil.java:185)

说明:

出现问题的类是getJsonValRecursive类,该类的第二个参数是默认的返回值,也是通过该参数来确定该方法的具体调用类型;

该类是用来获取Http返回之中的参数的,返回的json对象中可能包含好几层的json数据,需要通过关键字一层一层的进行获取,每一层关键字返回的结果都是服务器中所设定的,例如“code”关键字返回的int类型;“message”关键字返回的String类型,要根据不同的返回类型设置不同的变量来接收;该异常出现的原因就是用字符串类型的变量来接受int类型的返回值了。

publicstatic <T> TgetJsonValRecursive(JSONObjectobj, TdefaultValue, String... keys)

getJsonValRecursive(jsonObject,500,"meta","code");

解决方法:用对应类型的变量来接受对应的参数

 

6、Exception in thread "main"java.lang.NoClassDefFoundError:异常问题

NoClassDefFoundError异常,主要是jar包没有引入,或者没有在order中打对号;

Exception in thread"main" java.lang.NoClassDefFoundError:org/apache/commons/logging/LogFactory at org.apache.http.impl.client.AbstractHttpClient.<init>(AbstractHttpClient.java:187)atorg.apache.http.impl.client.DefaultHttpClient.<init>(DefaultHttpClient.java:146)at http.ClientConnUtil.get(ClientConnUtil.java:25)at test.ClientConnUtilTest.main(ClientConnUtilTest.java:8)

Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory at java.net.URLClassLoader.findClass(UnknownSource) atjava.lang.ClassLoader.loadClass(Unknown Source) atsun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source)

... 4 more

解决方案:

在程序中引入commons-logging jar包;

 

7、java.io.IOException:Attempted read from closed stream.异常问题

 

java.io.IOException: Attempted read from closed stream.

    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:172)

    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:204)

    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:155)

    at org.apache.http.util.EntityUtils.toByteArray(EntityUtils.java:120)

    at http.ClientConnUtil$uRunnable.run(ClientConnUtil.java:207)

    at java.util.concurrent.ThreadPoolExecutor.runWorker(UnknownSource)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(UnknownSource)

    at java.lang.Thread.run(Unknown Source)

报错的原因是,

EntityUtils.toString(entity)

这个方法只能调用一次,entity所得到的流是不可重复读取的也就是说所得的到实体只能一次消耗完,不能多次读取。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值