android.os.NetworkOnMainThreadException异常

本文介绍了一个在Android应用中遇到的主线程网络访问异常问题,并提供了两种解决方案:一是调整StrictMode设置来允许主线程网络访问;二是通过创建新线程来执行网络操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个异常大概意思是在主线程访问网络时出的异常。 Android在4.0之前的版本 支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。

为了把域名转化为ip地址,我在主线程中调用GetInetAddress函数。

复制代码
public static String GetInetAddress(String  host){//域名host转化为ip地址IPAddress返回
        String IPAddress = ""; 
        InetAddress ReturnStr1 = null;
        try {
            ReturnStr1 = java.net.InetAddress.getByName(host);
            IPAddress = ReturnStr1.getHostAddress();
            System.out.println(IPAddress);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return  IPAddress;
        }
        return IPAddress;
    }
复制代码

结果l出错,log信息为:

复制代码
01-15 09:16:50.340: E/AndroidRuntime(3927): FATAL EXCEPTION: main
01-15 09:16:50.340: E/AndroidRuntime(3927): android.os.NetworkOnMainThreadException
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at java.net.InetAddress.getByName(InetAddress.java:289)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at com.csipsimple.ui.HspLaunch.GetInetAddress(HspLaunch.java:655)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at com.csipsimple.ui.HspLaunch$LoginBtnListener.onClick(HspLaunch.java:264)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.view.View.performClick(View.java:4084)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.view.View$PerformClick.run(View.java:16966)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.os.Handler.handleCallback(Handler.java:615)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.os.Looper.loop(Looper.java:137)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at android.app.ActivityThread.main(ActivityThread.java:4746)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at java.lang.reflect.Method.invokeNative(Native Method)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at java.lang.reflect.Method.invoke(Method.java:511)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:917)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
01-15 09:16:50.340: E/AndroidRuntime(3927):     at dalvik.system.NativeStart.main(Native Method)
复制代码

解决方法有两个:
1、调用上面函数前,在onCreate函数里面添加如下代码:

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

2、使用Thread、Runnable、Handler这三个类

复制代码
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.hsp_login_dialog);
    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:在这里调用GetInetAddress函数处理,返回IPAddress.
        //
        Message msg = new Message();
        Bundle data = new Bundle();
        data.putString("value",IPAddress);
        msg.setData(data);
        handler.sendMessage(msg);
    }
}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值