Java 针对我的具体问题的好方法

Java 针对我的具体问题的好方法,java,android,sockets,server,Java,Android,Sockets,Server,我编写了一个客户端(android智能手机)-服务器(java)-程序 这只是为了练习,到目前为止,我只是向服务器发送一个字符串,并将其保存到一个文件中 目前,我想实施一项新功能,每5分钟将我的gps坐标发送到我的服务器并保存它 为此,我设置了一个AlarmManager,每3000000毫秒(或5分钟)接收一次广播 接收广播时,我希望与服务器建立连接: AlarmReceiver.class: public class AlarmReceiver extends BroadcastRe

我编写了一个客户端(android智能手机)-服务器(java)-程序

这只是为了练习,到目前为止,我只是向服务器发送一个字符串,并将其保存到一个文件中

目前,我想实施一项新功能,每5分钟将我的gps坐标发送到我的服务器并保存它

为此,我设置了一个
AlarmManager
,每3000000毫秒(或5分钟)接收一次广播

接收广播时,我希望与服务器建立连接:

AlarmReceiver.class:

    public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.e("alarmReceiver","received alarm");
        MainActivity activity = (MainActivity) context;
        activity.cConnect = new ConnectionThread(activity.clientServer, activity.out);
        activity.cConnect.start();
    }
    public class ConnectionThread extends Thread {

    Socket clientServer;
    BufferedWriter out;

    public ConnectionThread(Socket clientServer_, BufferedWriter out_) {
        // TODO Auto-generated constructor stub
        this.clientServer = clientServer_;
        this.out = out_;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        try {
            clientServer = new Socket(MainActivity.dstName, MainActivity.dstPort);

            out = new BufferedWriter(new OutputStreamWriter(clientServer.getOutputStream()));
            out.write("alarm received"); //currently just sending this string
            out.flush();
            out.close();
            clientServer.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
}

连接阅读类:

    public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.e("alarmReceiver","received alarm");
        MainActivity activity = (MainActivity) context;
        activity.cConnect = new ConnectionThread(activity.clientServer, activity.out);
        activity.cConnect.start();
    }
    public class ConnectionThread extends Thread {

    Socket clientServer;
    BufferedWriter out;

    public ConnectionThread(Socket clientServer_, BufferedWriter out_) {
        // TODO Auto-generated constructor stub
        this.clientServer = clientServer_;
        this.out = out_;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        try {
            clientServer = new Socket(MainActivity.dstName, MainActivity.dstPort);

            out = new BufferedWriter(new OutputStreamWriter(clientServer.getOutputStream()));
            out.write("alarm received"); //currently just sending this string
            out.flush();
            out.close();
            clientServer.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
在我的MainActivity.class中,我声明了以下内容:

protected static String dstName = ...
protected static int dstPort = ...
public Socket clientServer;
public BufferedWriter out;
private AlarmManager alarmMgr;
private static int repeatAlarmEvery = 30000;
private static int firstAlarmAfter = repeatAlarmEvery;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);...
我的问题是,当我的
AlarmReceiver
接收到广播并且已经在同一端口上建立了连接时,我正在尝试发送文本。。所以我决定只使用一个名为clientServer的
套接字对象,这样我就可以检查
clientServer!=null
->
不要建立新连接,而是使用现有连接

但是,尝试在模拟器上运行“我的客户端”程序时,出现以下错误:

06-03 19:24:29.969: E/AndroidRuntime(2186): Caused by: java.lang.ClassCastException: android.app.ReceiverRestrictedContext cannot be cast to com.example.clientservercommunication.MainActivity
06-03 19:24:29.969: E/AndroidRuntime(2186):     at com.example.clientservercommunication.AlarmReceiver.onReceive(AlarmReceiver.java:14)
我认为/看到的是,广播接收的上下文受到限制,我不允许将其投射到我的活动
main活动
。因此,我无法从
MainActivity.class
访问
clientSocket
out

现在我想到了两个解决方案:

1)声明
clientSocket
out
静态

2)为文本传输建立不同的连接(不同的端口),避免传输文本和gps坐标之间的冲突。e、 g.文本传输端口50000,gps数据传输端口50001

问题:

    public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.e("alarmReceiver","received alarm");
        MainActivity activity = (MainActivity) context;
        activity.cConnect = new ConnectionThread(activity.clientServer, activity.out);
        activity.cConnect.start();
    }
    public class ConnectionThread extends Thread {

    Socket clientServer;
    BufferedWriter out;

    public ConnectionThread(Socket clientServer_, BufferedWriter out_) {
        // TODO Auto-generated constructor stub
        this.clientServer = clientServer_;
        this.out = out_;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        try {
            clientServer = new Socket(MainActivity.dstName, MainActivity.dstPort);

            out = new BufferedWriter(new OutputStreamWriter(clientServer.getOutputStream()));
            out.write("alarm received"); //currently just sending this string
            out.flush();
            out.close();
            clientServer.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
哪一个更好(关于内存泄漏,如果可能的话等,不考虑意见,例如因为我更喜欢解决方案等)/更常见的方法还是有更好的设计模式/解决方案来实现我想要的


对于我来说,获得关于正确模式的支持是非常重要的,因为我厌倦了在没有足够的背景知识的情况下尝试它,并遇到了大量的问题。希望我能很好地描述我的问题。

BroadcastReceiver
中接收到的
上下文
不是
MainActivity
的实例。因此出现了
ClassCastException
。为什么不将您的
套接字
和相关实例移动到另一个不需要
MainActivity
实例的类中呢?我正在考虑创建一个全新的
holder类
,它只保存套接字和bufferedwriter。当收到报警时,我正在创建此特定类的
实例/对象
,并访问套接字和bufferedwriter。你是那个意思吗@nhaarman@nhaarman好的,这不能工作,因为我需要从不同的类访问holder类的实例。我目前正在使用静态套接字和bufferedwriter进行测试,到目前为止看起来还不错!请详细说明您的评论。我们无法看到您如何尝试发送文本。如果在同一端口上,则仍然可以使用其他连接。然后,服务器必须解决通过两个连接同时接收文本和坐标的情况。@greenapps确实可以看到。。现在我只是在连接中发送一个文本阅读现在我只想在单击transmit text按钮时启动run方法。获取gps坐标的实现是这个新功能的最后一项任务。是的,正如我在问题中所说,你的想法是我脑海中的第二个解决方案,但是如果将clientSocket和out声明为静态并设置一个标志(例如字符串的传输已经完成,gps坐标现在可以通过同一个con传输),那么这个解决方案有什么不好的地方吗?我最担心的是内存泄漏。