Android Socket入门小问题及使用127.0.0.1的问题

    还是课程设计的东西.这几天需要造一个Android客户端,可是鄙人安卓基础不行,一点一点搞.这几天有点收获,写出来,以此献给入坑的新手.

    我搞的是Ubuntu+Android Studio+MySQL+Android虚拟机.目的是Android虚拟机Socket连接Ubuntu,Ubuntu再与MySQL交互,然后把数据传到虚拟机.

    习惯了直接new一个Socket,但是在安卓onCreate中并不奏效啊..

坑(1)权限问题.

    这点我还比较清楚,毕竟大一搞过Android,把相关权限添加在AndroidManifest.xml文件中,具体位置是<Manifest>标签之内,<application>标签之外.例如我用的

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="liu.com.dev">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission>
    <uses-permission android:name="android.permission.INTERNET" ></uses-permission>
    <uses-permission android:name="android.permission.WAKE_LOCK" ></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

然后此程序就有访问网络的权限咯.

坑(2)android.os.NetworkOnMainThreadException

    字面意思是AndroidOS里面有个网络在主线程异常.当然啦,实际就是这个意思.

    Android官方文档

NetworkOnMainThreadException

public class NetworkOnMainThreadException 
extends RuntimeException 

java.lang.Object
   ↳java.lang.Throwable
    ↳java.lang.Exception
     ↳java.lang.RuntimeException
      ↳android.os.NetworkOnMainThreadException

 

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness.

    解决方案:当使用网络的时候new一个thread即可.

坑(3)android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views

    此处粘一篇写的很好的博客http://blog.sina.com.cn/s/blog_8401d4020100spss.html

比如在电话的应用程序中,有一个线程是RingTone,如果这个非UI线程中直接操作UI线程,会抛出android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views:

   1. Why

       为什么会有这种异常产生呢?

      当每个应用程序apk第一次启动时,Android会同时启动一个对应的主线程(Main Thread),

      主线程负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,

      并把相关的事件分发到对应的组件进行处理,所以主线程通常又被叫做UI线程。

      但是在开发Android应用时必须遵守单线程模型的原则: 

      Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,如果在非UI线程中直接操作UI线程,

      会抛出android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that 

      created a view hierarchy can touch its views,这与普通的java程序不同。

       由于UI线程负责事件的监听和绘图,因此,必须保证UI线程能够随时响应用户的需求,

       UI线程里的操作应该向中断事件那样短小,费时的操作(如网络连接)需要另开线程,

       否则,如果UI线程超过5s没有响应用户请求,会弹出对话框提醒用户终止应用程序(ANP)。

       如果在新开的线程中需要对UI进行设定,就可能违反单线程模型,

       因此android采用一种的Message Queue机制保证线程间通信。

       Message Queue是一个消息队列,用来存放通过Handler发送的消息。

       Android在第一启动程序时会默认会为UI thread创建一个关联的消息队列,

      可以通过Looper.myQueue()得到当前线程的消息队列,用来管理程序的一些上层组件,

      activities,broadcast receivers 等,你可以在自己的子线程中创建Handler与UI thread通讯。

      Handler会向message queue通过两种方法发送消息:send或post。

      这两种消息都会插在message queue队尾并按先进先出执行,

      但通过这两种方法发送的消息执行的方式略有不同:

      1)通过send发送的是一个message对象, 会被handler的 handleMessage()函数处理;

      2)而通过post方法发送的是一个runnable对象,则会自己执行。

      每个带图形界面的应用启动后,都会创建一个主线程,可称之为UI线程。

      这个线程自动就会创建一个message queue,来自于系统的消息都会投放到这个message queue里面,

      并按先进先出的顺序处理。

      UI线程图形界面中的view可通过post方法向GUI线程的message queue投递一个runnable。

     对于除UI线程以外的其他线程,创建时缺省并没有message queue,

     而对于UI线程,则可以直接(比如在onCreate)创建一个handler并重载handleMessage,

     省去创建message queue的过程。

坑(4)Socket使用127.0.0.1无法创建的问题

    平常两个java程序通信,本机地址127.0.0.1或者localhost都可以.可是..最近试安卓,这句话一直报错.试了一天了,最后改成通过ifconfig查看的本机ip,居然bingo了!!!哈哈哈,至于为什么可以了呢?我揣测,127.0.0.1代表的是Android虚拟机的127.0.0.1,并不是Ubuntu的localhost,所以创建一直失败.当然这是个人的理解,有知道的请赐教,不胜感激涕零.        

转载于:https://my.oschina.net/u/3008297/blog/815992

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值