仍是课程设计的东西.这几天须要造一个Android客户端,但是鄙人安卓基础不行,一点一点搞.这几天有点收获,写出来,以此献给入坑的新手.html
我搞的是Ubuntu+Android Studio+MySQL+Android虚拟机.目的是Android虚拟机Socket链接Ubuntu,Ubuntu再与MySQL交互,而后把数据传到虚拟机.java
习惯了直接new一个Socket,可是在安卓onCreate中并不奏效啊..android
坑(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>
而后此程序就有访问网络的权限咯.app
坑(2)android.os.NetworkOnMainThreadExceptionide
字面意思是AndroidOS里面有个网络在主线程异常.固然啦,实际就是这个意思.函数
Android官方文档oop
public class NetworkOnMainThreadException
extends RuntimeException
post
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,因此建立一直失败.固然这是我的的理解,有知道的请赐教,不胜感激不尽.