Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题
一、Android:Socket客戶端開發
創建一個工程
我們要做的是按下按鍵之后,去往服務器
(服務器)
或者我們自己寫的服務器
,給他發送一些預定好的東西
? ? ??
然后打開操作界面
?然后修改一下
你要發送消息,需要
android:onClick="sendMessage"
?然后在這里
?修改一下
?如何發送?
CTRL + shirt? +? ?o? ?打包
?當按鍵被按下的時候,我們就做這些
?把這些扔進來
當按鍵被按下的時候,我們調用????????sendMessage 這個東西
調用這個東西我們干啥呢?? ? ? ? 連接????????Socket client = new Socket("192.168.70.1", 9002);
?? ??? ??? ?????????????????????????????????????????????????OutputStream out= client.getOutputStream();
連接以后我們不要用????????????????Scanner sc = new Scanner(System.in);
?? ??? ??????????????????????????????????????????????????? ?String message = sc.next();
????????????????????????????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
我們定義一個????????String message = "message from Android";
out.write(message.getBytes());? ? ? ? 這句話也得改一下
?????????然后????????????????
?? ??? ??????????? ?InputStream in = client.getInputStream();?? ??? ??? ?
?? ??? ??????????? ?int len;
?? ??? ??????????? ?byte[]data = new byte[128];
?? ??? ??????????? ?len = in.read(data);
?? ??? ??????????? ?System.out.println("獲得服務端返回數據是:"+new String(data,0,len));
? ? ? ? 先不做,????????獲得數據我們先不做,先發一個數據??????
現在 的代碼
??
?
運行一下
?在夜神模擬器上顯示的結果
?點一下發送信息
?然后我們試一下,之前寫過的JavaSocket服務端
運行一下
?顯示? ? ? ? 等待連接
?然后,我們點擊一下? ?夜神模擬器上面的發送消息
?顯示已經停止運行
然后logCat最大化
?我們從第三行紅字開始看
?再看一下caused by
?
?Network網絡訪問? ? ? ? onMainThreadException? 放在主線程里面的異常
他不讓你在主線程里面發送網絡訪問
????????開始我們看第三行,還以為方法找不到嗎,實際上它找到了,找到以后進行網絡訪問的時候崩了,他不讓你在主線程里面做網絡訪問
????????那如何解決呢?
? ? ? ? 把
????????try {
?? ??? ??????????? ?Socket client = new Socket("192.168.70.1",9002);
?? ??? ??????????? ?OutputStream out= client.getOutputStream();
?? ??? ??? ?
?? ??????????? ??? ?String message = "message from Android";
?? ??? ??????????? ?out.write(message.getBytes());
????????//?? ??? ??? ?
????????//?? ??? ??? ?InputStream in = client.getInputStream();?? ??? ??? ?
????????//?? ??? ??? ?int len;
????????//?? ??? ??? ?byte[]data = new byte[128];
????????//?? ??? ??? ?len = in.read(data);
????????//?? ??? ??? ?System.out.println("獲得服務端返回數據是:"+new String(data,0,len));
?? ??? ??? ?
?????????? ??? ?}?
?? ??????????? ?catch (IOException e) {
?? ??? ??????????? ?// TODO Auto-generated catch block
?? ??? ??????????? ?e.printStackTrace();
?? ??????????? ?}
這個東西做成函數分裝????????
?public void sendMessageHandler()
? ? {
? ? ?? ?????????????????????????
? ? ?? ?????????????????
? ? }
????????然后在這個handler里面,做真正的網絡請求,就是try那一部分
? ??????????
? ? ? ? 按鍵被按下的時候,我們是不是要啟動一個線程呀????????new Thread().strat();
在Thread().? ? ?加上new runnable
?變成了
在Runnable里面做你真正想要做的事?
?現在的代碼:
????????????????????????
JavaSocket服務端
????????????????
?安卓Socket客戶端:
?
?先運行一下JavaSocket服務端
????????
顯示
修改一下28行
String message = "message from Android";
?然后在運行一下? 安卓Socket客戶端:
運行結果
????????點擊發送消息
? ? ? ? 然后顯示:有客戶端接入
讀到消息:message from Android
補充:
,這里最好不要直接從別的地方復制過來代碼,要不然容易顯示錯誤
?
二、Android 的Socket客戶端優化
那么如果我們有多個按鍵
然后我們把這四個拖拽一下,在改一下名字
在改一下id
?
然后我們在 MainActivity上面要做一個處理
而不是所有的都是走它?????????? ?new Thread(new Runnable() {
?? ??? ??? ?
?? ??? ??????????? ?????????????????????????????????@Override
?? ??? ??????????????????????????????????????????? ?public void run() {
?? ??? ??? ??????????????????????????????????????????? ?// TODO Auto-generated method stub
?? ??? ??? ??????????????????????????????????????????? ?sendMessageHandler();
?? ??? ??????????????????????????????????????????? ?}
?? ??????????????????????????????????? ?}).start();
????????
你在這里想干什么事?
?再來個后退
但是有點不妥,不管前進還是后退,他調用的api都是一樣的,發送的消息都是一樣的
如何辦呢?傳參唄。
? ? ? ? 同時:? ? ? ? ? ? ? ? 變成public void sendMessageHandler(String command)
??????????????????????????????????????out.write(message.getBytes());改成????????out.write(command.getBytes());
這樣函數就分裝了
然后??
?String message = "message from Android";這句話就不要了
?
?
同理做出來左右的代碼‘
?運行一下
?然后(記得先運行JAVASocket服務端,然后在運行安卓Socket客戶端)
?現在的代碼,還能進行優化
你每個都在new Thread(new Runnable() {
? ? ?? ??? ??? ?
? ? ?? ??? ??? ?@Override
? ? ?? ??? ??? ?public void run() {
? ? ?? ??? ??? ??? ?// TODO Auto-generated method stub
? ? ?? ??? ??? ??? ?sendMessageHandler("goback");
? ? ?? ??? ??? ?}
? ? ?? ??? ?}).start(); ? ??? ??? ?
?
然后把?
???????? try {
?? ??? ??? ?Socket client = new Socket("192.168.70.1", 8810);
?? ??? ??? ?OutputStream out= client.getOutputStream();
?? ??? ??? ?out.write(command.getBytes());
?? ??? ?????????
?? ??? ??? ?????????
?? ??? ?}?
?? ??? ?catch (IOException e) {
?? ??? ??? ?// TODO Auto-generated catch block
?? ??? ??? ?e.printStackTrace();
?? ??? ?}?
copy一下,放到run里面
可是現在的command我們拿不到
?解決方法
?下面也可以修改一下
如果想變得整齊的話
思路: 按鍵被按下的時候,根據不同的id做不同的事情
運行一下
?現在的代碼
?
還可以改動一下
你會發現這個方法是單獨的
我們可以
然后
?在改動一下,變成靜態的變量
?這樣你主線程里面的代碼就會很舒服
稍加改動一下
記得還要ctrl? + shirt? +o? 把包導進來
?
運行一下
三、Android非UI線程修改控件程序崩潰的問題
我們安卓客戶端進行網絡訪問,難免會收到來自服務端的消息,我們上面只是負責發,沒有負責收
如果收到消息的話,我們希望讓他顯示在控件上面
?里面的內容
先把沒用的去掉
在這個Activity里面有一個TextView
?
給他來個id?????????android:id="@+id/textView"
那么xml 和前面如何關聯呢?? ? ? ? ?在.java 里面????????? public TextView textview;
記得ctrl? ?+ shirt? ?+ o? ?打包
然后
然后?
?
然后
?做一個強制轉換,CTRL? ?+? ?1? ? 然后回車
我們下一步拖個按鍵進來
?
比如這個按鍵的目標是修改textView????????android:text="修改textView為lzp" />
在作一個測試的函數????????android:onClick="testFunc"
然后在.Java里面
?記得ctrl? +? shirt? ?+? ?o? 打包
?然后
?修改一下內容
?運行一下
?點擊一下
?那如果我現在想要動態的 刷新
?還需要try? catch?
然后
把?? ?textView.setText("lizhaopeng");? ?改成??????????? ?textView.setText("lizhaopeng"+i);
運行一下
發現卡在這里不動了
?那他有沒有再跑?
看看能不捕捉到
System.out.println("lizhaopeng"+i);
運行一下,發現一點也沒動
?那01234567哪去了?
在UI線程中,不要sleep????????,你真的想sleep你應該創建一個線程sleep?????????? ?new Thread().start();
?你是不是想把????????textView.setText("lizhaopeng"+i);放進去
但是現在這個i不認識
?修改一下
按下按鍵以后,啟動一個線程,這個線程里面去數秒,每隔一秒,修改一次標簽
現在的代碼
這樣主線程就不會阻塞,UI線程就不會被sleep影響,在UI線程之外去操控UI
運行一下
崩調了
我們在UI上顯示網絡請求,肯定是在線程里面
只是我把網絡請求這個事情,我們用for循環做一個簡單除暴的信息的變化,然后刷到textView上面去,原理都一樣
總結
以上是生活随笔為你收集整理的Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java:socket服务端,socke
- 下一篇: android 关机 流程_Androi