我正在尝试创建远程服务,该服务将负责少数不同应用程序的所有客户端-服务器通信。主要思想是从主要活动启动服务并打开与服务器的通信套接字。在那之后,套接字将被其他应用程序使用——这就是我想为它使用远程服务的原因......
现在我的套接字连接有问题,它在我的设备上引发空异常。它在使用较旧的 android 版本的 AVD 上运行良好。
这是我的代码的一些部分:
我的主要活动:
final ServiceConnection conn = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
myRemoteService = ConnectionInterface.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName name) {
myRemoteService = null;
}
};
final Thread t = new Thread(){
public void run(){
bindService(new Intent(getApplicationContext(), ConnectionRemoteService.class),conn,Context.BIND_AUTO_CREATE);
while(true){}
}
};
稍后我用 t.start() 启动线程 t;
我的连接远程服务:
package com.mainlauncher;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ResourceBundle;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.widget.Toast;
public class ConnectionRemoteService extends Service {
private static final int SERVERPORT = 7777;
private static final String SERVERADDRESS = "192.168.1.106";
private String deviceID;
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
@Override
public void onCreate() {
super.onCreate();
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
deviceID = wm.getConnectionInfo().getMacAddress();
Toast.makeText(this, "Service On.", Toast.LENGTH_LONG).show();
open();
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service Off.", Toast.LENGTH_LONG).show();
close();
}
@Override
public IBinder onBind(Intent intent) {
return myRemoteServiceStub;
}
private ConnectionInterface.Stub myRemoteServiceStub = new ConnectionInterface.Stub() {
};
void open(){
try{
socket = new Socket(SERVERADDRESS,SERVERPORT);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(deviceID);
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
void close(){
try {
if(in!=null)
in.close();
if(out!=null)
out.close();
if(socket!=null)
socket.close();
}
catch(Exception e){
System.err.println(e.getMessage());
}
socket=null;
}
}
主要清单文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mainlauncher"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name=".MainLauncherWindow" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ConnectionRemoteService"
android:process=":remote"/>
</application>
这是根据要求在“调试”模式下的 DDMS 日志:
pid=20210 11-06 12:13:45.240: I/ActivityManager(392): 启动 proc com.mainlauncher: 远程服务 com.mainlauncher/.ConnectionRemoteService: pid=20210 uid=10080 gids={3003} 11-06 12 :13:45.300: D/ConnSrv_Debug(392): 在 20210/10080 11-06 12:13:45.300 之前获取 mDefaultProxy null: D/WifiStateMachine(392): syncRequestConnectionInfo mWifiInfo=SSID: linksys, BSSID: 00:14:bf: e6:13:8f, MAC: 18:87:96:88:cd:68, 请求者状态: COMPLETED, RSSI: -83, Link speed: 36, Frequency: 2462, Net ID: 1, Explicit connect: false 11- 06 12:13:45.320: D/AndroidRuntime(20210): 关闭 VM 11-06 12:13:45.320: W/dalvikvm(20210): threadid=1: 线程以未捕获的异常退出 (group=0x40a6b228) 11-06 12:13:45.320:E/EmbeddedLogger(392):应用程序崩溃了!进程:com.mainlauncher:remote 11-06 12:13:45.320: E/EmbeddedLogger(392): App 崩溃了!包:com.
我在这一行得到了例外:
socket = new Socket(SERVERADDRESS,SERVERPORT);
我知道很少有事情可以使这个例外:1.我<uses-permission android:name="android.permission.INTERNET" />
在我的主要清单中使用。2. Service 在单独的线程下运行,而不是在主活动线程上。3.没有防火墙等... 4.我已经检查了与服务器的连接(没有服务一切正常)。5. 我也在清单中使用 android:process=":remote"。
任何想法为什么会发生这种异常?我如何调试它以获取更多详细信息?
它在使用 OS 2.3 的 AVD 上有效,所以我认为这是主活动线程异常的问题,但我不知道为什么。
谢谢,利奥兹。