Java 套接字连接的Singleton类不工作
我创建了一个singleton类来启用socket连接,它返回一个socket对象,应用程序中的任何活动都可以使用该对象。 singleton类如下所示Java 套接字连接的Singleton类不工作,java,android,sockets,design-patterns,singleton,Java,Android,Sockets,Design Patterns,Singleton,我创建了一个singleton类来启用socket连接,它返回一个socket对象,应用程序中的任何活动都可以使用该对象。 singleton类如下所示 public class Singleton { private static Socket socket; private DataInputStream input; private DataOutputStream output; private boolean logged; private static Singleton inst
public class Singleton
{
private static Socket socket;
private DataInputStream input;
private DataOutputStream output;
private boolean logged;
private static Singleton instance;
private String information;
private static final int SERVERPORT = 8020;
private static final String SERVER_IP = "192.168.1.33";
static PrintWriter out;
private Singleton()
{
}
public static Singleton getInstance()
{
return instance;
}
public static void initSingleton()
{
if(instance == null)
{
instance = new Singleton();
InetAddress serverAddr = null;
try {
serverAddr = InetAddress.getByName(SERVER_IP);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket = new Socket(serverAddr, SERVERPORT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Socket getSocket()
{
return socket;
}
public PrintWriter getOutput()
{
return out;
}
}
在main活动中,我调用singleton类
public class MainActivity extends Activity implements OnItemSelectedListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initSingleton(); }
protected void initSingleton()
{
Singleton.initSingleton();
}
public void onClickon(View view) {
Socket socket = Singleton.getInstance().getSocket();
try{
PrintWriter out=Singleton.getInstance().getOutput();
out.println("0");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
单击按钮时,将调用onClickon函数,该函数使用Singleton类的getSocket()和getOutput()函数返回对象类型
但是应用程序崩溃了
日志如下所示。
05-08 11:33:41.236: E/AndroidRuntime(19813): FATAL EXCEPTION: main
05-08 11:33:41.236: E/AndroidRuntime(19813): Process: com.example.clientmobile2, PID: 19813
05-08 11:33:41.236: E/AndroidRuntime(19813): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.clientmobile2/com.example.clientmobile2.MainActivity}: android.os.NetworkOnMainThreadException
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread.access$800(ActivityThread.java:139)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.os.Handler.dispatchMessage(Handler.java:102)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.os.Looper.loop(Looper.java:136)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread.main(ActivityThread.java:5102)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.lang.reflect.Method.invokeNative(Native Method)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.lang.reflect.Method.invoke(Method.java:515)
05-08 11:33:41.236: E/AndroidRuntime(19813): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
05-08 11:33:41.236: E/AndroidRuntime(19813): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
05-08 11:33:41.236: E/AndroidRuntime(19813): at dalvik.system.NativeStart.main(Native Method)
05-08 11:33:41.236: E/AndroidRuntime(19813): Caused by: android.os.NetworkOnMainThreadException
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
05-08 11:33:41.236: E/AndroidRuntime(19813): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
05-08 11:33:41.236: E/AndroidRuntime(19813): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
05-08 11:33:41.236: E/AndroidRuntime(19813): at libcore.io.IoBridge.connect(IoBridge.java:112)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.net.Socket.startupSocket(Socket.java:566)
05-08 11:33:41.236: E/AndroidRuntime(19813): at java.net.Socket.<init>(Socket.java:226)
05-08 11:33:41.236: E/AndroidRuntime(19813): at com.example.clientmobile2.Singleton.initSingleton(Singleton.java:48)
05-08 11:33:41.236: E/AndroidRuntime(19813): at com.example.clientmobile2.MainActivity.initSingleton(MainActivity.java:148)
05-08 11:33:41.236: E/AndroidRuntime(19813): at com.example.clientmobile2.MainActivity.onCreate(MainActivity.java:101)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.Activity.performCreate(Activity.java:5248)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
05-08 11:33:41.236: E/AndroidRuntime(19813): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
05-08 11:33:41.236:E/AndroidRuntime(19813):致命异常:main
05-08 11:33:41.236:E/AndroidRuntime(19813):进程:com.example.clientmobile2,PID:19813
05-08 11:33:41.236:E/AndroidRuntime(19813):java.lang.RuntimeException:无法启动活动组件信息{com.example.clientmobile2/com.example.clientmobile2.MainActivity}:android.os.networkMainThreadException
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.ActivityThread.access$800(ActivityThread.java:139)
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.os.Handler.dispatchMessage(Handler.java:102)上
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.os.Looper.loop(Looper.java:136)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于android.app.ActivityThread.main(ActivityThread.java:5102)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于java.lang.reflect.Method.Invokenactive(本机方法)
05-08 11:33:41.236:E/AndroidRuntime(19813):在java.lang.reflect.Method.invoke(Method.java:515)
05-08 11:33:41.236:E/AndroidRuntime(19813):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
05-08 11:33:41.236:E/AndroidRuntime(19813):在dalvik.system.NativeStart.main(本机方法)
05-08 11:33:41.236:E/AndroidRuntime(19813):由以下原因引起:android.os.NetworkOnMainThreadException
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
05-08 11:33:41.236:E/AndroidRuntime(19813):在libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)上
05-08 11:33:41.236:E/AndroidRuntime(19813):在libcore.io.IoBridge.connecterno(IoBridge.java:127)
05-08 11:33:41.236:E/AndroidRuntime(19813):在libcore.io.IoBridge.connect(IoBridge.java:112)
05-08 11:33:41.236:E/AndroidRuntime(19813):在java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-08 11:33:41.236:E/AndroidRuntime(19813):在java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于java.net.Socket.startupSocket(Socket.java:566)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于java.net.Socket(Socket.java:226)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于com.example.clientmobile2.Singleton.initSingleton(Singleton.java:48)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于com.example.clientmobile2.MainActivity.initSingleton(MainActivity.java:148)
05-08 11:33:41.236:E/AndroidRuntime(19813):位于com.example.clientmobile2.MainActivity.onCreate(MainActivity.java:101)
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.Activity.performCreate(Activity.java:5248)上
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)上
05-08 11:33:41.236:E/AndroidRuntime(19813):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
此代码:
protected void initSingleton()
{
Singleton.initSingleton();
}
在尝试获取实例之前不执行,即使您正在调用该函数onCreate()
。为什么要在单独的方法上实例化单例,而不是在getInstance()
中实例化它
将代码更改为这样,以避免在调用Singleton而实例不存在时出现此类问题
public static Singleton getInstance()
{
if(instance == null)
initSingleton();
return instance;
}
private static void initSingleton()
{
instance = new Singleton();
InetAddress serverAddr = null;
try
{
serverAddr = InetAddress.getByName(SERVER_IP);
}
catch (UnknownHostException e)
{
System.err.println("Fail when getting Server Address.");
}
try
{
socket = new Socket(serverAddr, SERVERPORT);
}
catch (IOException e)
{
System.err.println("Failed creating new socket.");
}
try
{
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
}
catch (IOException e)
{
System.err.println("EPIC FAIL HERE");
}
}
主要活动:
public class MainActivity extends Activity implements OnItemSelectedListener
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickon(View view)
{
Socket socket = Singleton.getInstance().getSocket();
try
{
PrintWriter out=Singleton.getInstance().getOutput();
out.println("0");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
FunctionR的解决方案是正确的,但它不是线程安全的,因此一种解决方案可以是在静态初始值设定项中实例化singleton变量,或者使用同步块使singleton实例化线程安全()。一个主要问题是,您不能在主线程上运行像远程连接这样代价高昂的操作。。e、 t.c, 我的意思是,您为这个套接字连接创建新线程,否则使用异步任务将重新解决您的问题
注意:请不要忘记关闭连接您好,我尝试了我们的代码,做了一些修改,效果很好。对于我来说,我实例化了套接字,并在执行中的头中实现了initSingleton() 主要活动
公共类ConnectActivity扩展活动{
插座客户端插座;
单例;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
instance=newsingleton();
新线程(新ClientThread()).start();
//Socket-Socket=Singleton.getInstance().getSocket();
}
受保护的void initSingleton()
{
initSingleton();
}
类ClientThread实现Runnable{
@凌驾
公开募捐{
initSingleton();
Socket-Socket=Singleton.getInstance().getSocket();
}
}
为什么麻烦?新套接字(…)
只是一行代码。@EJP您能详细说明一下吗?是您在详细说明。您正在创建20行代码,一行就可以了。嘿,谢谢