仍是課程設計的東西.這幾天須要造一個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,因此建立一直失敗.固然這是我的的理解,有知道的請賜教,不勝感激不盡.