www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]前幾天學(xué)習(xí)了 Android 下 Socket 編程。學(xué)習(xí) Socket 編程是有目的的,需要完成在手機(jī)與 PC 之間的通訊。通訊的內(nèi)容是將手機(jī)上播放的 MP3 信息,通過(guò) Socket 傳輸?shù)?PC

前幾天學(xué)習(xí)了 Android 下 Socket 編程。

學(xué)習(xí) Socket 編程是有目的的,需要完成在手機(jī)與 PC 之間的通訊。通訊的內(nèi)容是將手機(jī)上播放的 MP3 信息,通過(guò) Socket 傳輸?shù)?PC 端。
在參考網(wǎng)上相關(guān) Socket 的文章后,基本上完成了 Socket 功能。所以就繼續(xù)學(xué)習(xí) Android 下音樂(lè)播放器的實(shí)現(xiàn)。在實(shí)現(xiàn)音樂(lè)播放器過(guò)程中,發(fā)現(xiàn)由于音樂(lè)播放器至少要有播放列表和正在播放兩個(gè) Activity,這樣問(wèn)題就來(lái)了:
(1). Socket 只是在第一個(gè) Activity 中實(shí)現(xiàn)了,當(dāng)這個(gè) Activity 活動(dòng)時(shí)沒(méi)有問(wèn)題。但此 Activity 非活動(dòng)時(shí),不能處理 Socket。
(2). 當(dāng)反復(fù)進(jìn)入第一個(gè) Activity 時(shí),會(huì)出現(xiàn) Socket 初始化報(bào)錯(cuò)的問(wèn)題。出現(xiàn)這樣的錯(cuò)誤,是由于 Sokcet 的初始化放在第一個(gè) Activity 的 onCreate 中。

由于在做音樂(lè)播放器時(shí)使用了 Service,所以想到用 Serivce 來(lái)處理 Socket 應(yīng)該沒(méi)有問(wèn)題。但是否有其它的方法呢?由于個(gè)人是剛剛接觸 Android 編程,就不能確定這個(gè)問(wèn)題了!
在論壇提問(wèn),得到的答案是:(1) Serivce; (2) 也可以更改activity的啟動(dòng)方式,讓串口不重復(fù)創(chuàng)建。顯然,第二種方法還沒(méi)有接觸過(guò)。采用第一種 Serivce 來(lái)實(shí)現(xiàn)更可靠一些。


首先,實(shí)現(xiàn) Socket Service。

package?com.jia.leozhengfirstapp;


import?java.io.IOException;
import?java.io.InputStream;
import?java.io.UnsupportedEncodingException;
import?java.net.ServerSocket;
import?java.net.Socket;


import?android.app.Service;
import?android.content.BroadcastReceiver;
import?android.content.Context;
import?android.content.Intent;
import?android.content.IntentFilter;
import?android.os.IBinder;
import?android.util.Log;


public?class?SocketService?extends?Service?{


??private?Socket?clientSocket?=?null;
??private?ServerSocket?mServerSocket?=?null;


??private?SocketAcceptThread?socketAcceptThread?=?null;
??private?SocketReceiveThread?socketReceiveThread?=?null;


??private?SocketReceiver?socketReceiver;


??public?static?final?String?SOCKER_ACTION?=?"com.jia.Socket.Control";
??public?static?final?String?SOCKER_RCV?=?"com.jia.Socket.ReceiveStr";


??private?boolean?stop?=?true;


??@Override
??public?IBinder?onBind(Intent?intent)?{
????//?TODO?Auto-generated?method?stub
????return?null;
??}
???@Override
??public?void?onCreate()?{
??????????super.onCreate();
??????????Log.d("service",?"socket?service?created");
??????????socketReceiver?=?new?SocketReceiver();
??????????IntentFilter?filter?=?new?IntentFilter();
??????????filter.addAction(SOCKER_ACTION);
??????????registerReceiver(socketReceiver,?filter);


??????????socketAcceptThread?=?new?SocketAcceptThread();
????????????//?開(kāi)啟?Socket?監(jiān)聽(tīng)線程
????????????socketAcceptThread.start();
???}


??@Override
??public?void?onStart(Intent?intent,?int?startId)?{
?????Log.d("service",?"socket?service?start");


??}


??@Override
??public?void?onDestroy()?{
??Log.d("service",?"socket?service?destroy!");


??}


??public?class?SocketReceiver?extends?BroadcastReceiver?{


????@Override
????public?void?onReceive(Context?context,?Intent?intent)?{
??????String?action?=?intent.getAction();
????????????if(action.equals(SOCKER_ACTION))?{
??????????????String?sub_action?=?intent.getExtras().getString("ACTION");
??????????????if(sub_action.equals("reconnect"))?{
????????????????Log.d("service",?"socket?service:?reconnect.");


?????????????????socketAcceptThread?=?new?SocketAcceptThread();
??????????????????//?開(kāi)啟?Socket?監(jiān)聽(tīng)線程
??????????????????socketAcceptThread.start();
??????????????}
????????????}
????}
??}


??private?class?SocketAcceptThread?extends?Thread
??{
???????@Override
???????public?void?run()
???????{
?????????Log.d("service",?"socket?service?-?SocketAcceptThread::run");
???????????try?{
???????????????//?實(shí)例化ServerSocket對(duì)象并設(shè)置端口號(hào)為?12589
???????????????mServerSocket?=?new?ServerSocket(12589);
???????????}?catch?(IOException?e)?{
???????????????//?TODO?Auto-generated?catch?block
???????????????e.printStackTrace();
???????????}


???????????try?{
???????????????//?等待客戶端的連接(阻塞)
???????????????clientSocket?=?mServerSocket.accept();
???????????}?catch?(IOException?e)?{
???????????????//?TODO?Auto-generated?catch?block
???????????????e.printStackTrace();
???????????}


???????????socketReceiveThread?=?new?SocketReceiveThread(clientSocket);
???????????stop?=?false;
???????????//?開(kāi)啟接收線程
???????????socketReceiveThread.start();


?????????????Intent?sendIntent?=?new?Intent(SOCKER_RCV);
?????????????sendIntent.putExtra("action",?"ClientIP");
?????????????sendIntent.putExtra("content",?clientSocket.getInetAddress().getHostAddress());
?????????????//?發(fā)送廣播,將被Activity組件中的BroadcastReceiver接收到
?????????????sendBroadcast(sendIntent);
???????}
???}


???private?class?SocketReceiveThread?extends?Thread
???{
???????private?InputStream?mInputStream?=?null;
???????private?byte[]?buf;
???????private?String?str?=?null;
???????Socket?sUsed;


???????SocketReceiveThread(Socket?s)
???????{
?????????Log.d("service",?"socket?service?-?SocketReceiveThread");
???????????try?{
???????????????//?獲得輸入流
???????????????this.mInputStream?=?s.getInputStream();
???????????????sUsed?=?s;
???????????}?catch?(IOException?e)?{
???????????????//?TODO?Auto-generated?catch?block
???????????????e.printStackTrace();
???????????}
???????}


???????@Override
???????public?void?run()
???????{
?????????Log.d("service",?"socket?service?-?SocketReceiveThread::run");
???????????while((!stop)?&&?(!mServerSocket.isClosed()))
???????????{
???????????????this.buf?=?new?byte[2048];


???????????????//?讀取輸入的數(shù)據(jù)(阻塞讀)
???????????????try?{
???????????????????this.mInputStream.read(buf);
???????????????}?catch?(IOException?e1)?{
???????????????????//?TODO?Auto-generated?catch?block
???????????????????e1.printStackTrace();
???????????????}


???????????????//?字符編碼轉(zhuǎn)換
???????????????try?{
???????????????????this.str?=?new?String(this.buf,?"GB2312").trim();
???????????????}?catch?(UnsupportedEncodingException?e)?{
???????????????????//?TODO?Auto-generated?catch?block
???????????????????e.printStackTrace();
???????????????}


???????????????Intent?sendIntent?=?new?Intent(SOCKER_RCV);
???????????????sendIntent.putExtra("action",?"RcvStr");
???????????????sendIntent.putExtra("content",?this.str);
???????????????//?發(fā)送廣播,將被Activity組件中的BroadcastReceiver接收到
???????????????sendBroadcast(sendIntent);
???????????}
???????}
???}
}



在每個(gè) Activity 中處理 SOCKER_RCV action,以響應(yīng) Socket 狀態(tài)的變化和接收到數(shù)據(jù)。
Service 與 Activity 之間通訊需要使用到廣播: Broadcast。
(1) 在 Activity 中定義全局的變量,如下:

public?static?final?String?SOCKER_ACTION?=?"com.jia.Socket.Control";
public?static?final?String?SOCKER_RCV?=?"com.jia.Socket.ReceiveStr";


SocketReceiver?socketReceiver;



(2) 在 Activity 的 onCreate 中注冊(cè)廣播和啟動(dòng) Socket Service,如下:

socketReceiver?=?new?SocketReceiver();
IntentFilter?socketIntentFilter?=?new?IntentFilter();
socketIntentFilter.addAction(SOCKER_RCV);
registerReceiver(socketReceiver,socketIntentFilter);


Intent?socketIntent?=?new?Intent();
socketIntent.setClass(MainActivity.this,?SocketService.class);
startService(socketIntent);???????//?啟動(dòng)??Socket?服務(wù)



(3) SocketReceiver 是繼承自 BroadcastReceiver 的類(lèi),實(shí)現(xiàn)如下:

public?class?SocketReceiver?extends?BroadcastReceiver?{


??@Override
??public?void?onReceive(Context?context,?Intent?intent)?{
????//?TODO?Auto-generated?method?stub
????String?action?=?intent.getAction();
??????????if(action.equals(SOCKER_RCV))?{
????????????String?url?=?intent.getExtras().getString("action");
????????????if(url.equals("ClientIP"))?{
??????????????String?strIP?=?intent.getExtras().getString("content");
????????????}
????????????else?if(url.equals("RcvStr"))?{
??????????????String?strContent?=?intent.getExtras().getString("content");
????????????}
????????????else?if(url.equals("Disconnect"))?{
??????????????String?strContent?=?intent.getExtras().getString("content");
????????????}
????????}
????}
}



(4) Socket 功能實(shí)現(xiàn)后,測(cè)試時(shí)發(fā)現(xiàn)客戶端(也就是 PC 端)斷開(kāi)時(shí)手機(jī)端未檢測(cè)到 Socket 連接斷開(kāi)。
以前使用 WinCE 時(shí),Socket(TCP) 斷開(kāi)時(shí),無(wú)論是客戶端、還是服務(wù)器都可以檢測(cè)到 TCP 斷開(kāi)的事件,并處理。但 Android 下的 Socket 編程機(jī)制竟然沒(méi)有這個(gè)東東。
一,測(cè)試時(shí)發(fā)現(xiàn)當(dāng) PC 端斷開(kāi)后,手機(jī)端的服務(wù)程序在執(zhí)行到下面的代碼段時(shí)不會(huì)阻塞,且函數(shù)的返回值是: -1。
二,在網(wǎng)上查找發(fā)現(xiàn)這個(gè)問(wèn)題是 Android 下 Socket 都有的問(wèn)題,可以通過(guò)發(fā)心跳包來(lái)處理。
所以將下面這段代碼:

//?讀取輸入的數(shù)據(jù)(阻塞讀)
try?{
????this.mInputStream.read(buf);
}?catch?(IOException?e1)?{
????//?TODO?Auto-generated?catch?block
????e1.printStackTrace();
}
修改為如下的代碼:?
try?{
????int?length?=?this.mInputStream.read(buf);
????if(-1?==?length)?{
??????try?{
????????sUsed.sendUrgentData(0xff);
??????}
??????catch(Exception?ex)?{
????????//?鏈接已斷開(kāi)
????????Log.v("service",?"disconnect!!!");
????????stop?=?true;
????????if(null?!=?mServerSocket)?{
??????????mServerSocket.close();
????????}


????????Intent?sendIntent?=?new?Intent(SOCKER_RCV);
????????sendIntent.putExtra("action",?"Disconnect");
????????sendIntent.putExtra("content",?"read?is?-1?&?Urgent?Exception!");
????????sendBroadcast(sendIntent);


????????continue;
??????}
????}
}?catch?(IOException?e1)?{
????//?TODO?Auto-generated?catch?block
????e1.printStackTrace();
}
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉