当我打开我的应用程序不止一个时,为什么我的android中的线程不止一次运行?

时间:2014-08-20 14:47:28

标签: android eclipse

我有这个代码在android .my代码是为了回复多播msg.it正常工作当我打开这个应用程序的第一个。但我使用按钮返回Android和我打开第二,这个应用程序工作不止一个并回复多个回复。

public class MainActivity extends Activity {

    TextView info, infoip, msg;
     String message = "";
     ServerSocket serverSocket;
     String s;

      String ipserver;

      String replyip;
       int i;
       int j;

     @Override
     protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      info = (TextView) findViewById(R.id.info);
      infoip = (TextView) findViewById(R.id.infoip);
      msg = (TextView) findViewById(R.id.msg);
      i=0;
      j=1;
      infoip.setText(getIpAddress());
      WifiManager manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
      WifiInfo infor =manager.getConnectionInfo();
      String addr=infor.getMacAddress();
      this.s=addr;


    Thread t = new Thread (new SocketServerThread());
    if(!t.isAlive()){
    t.start();
    }


     }

     @Override
     protected void onRestart(){


     }


     @Override
     protected void onDestroy() {
      super.onDestroy();
     i=1;
     j=0;


      if (serverSocket != null) {
       try {
        serverSocket.close();
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
     }

     private class SocketServerThread extends Thread {

      static final int SocketServerPORT = 7000;
      int count = 0;

      @Override
      public void run() {
       try {
        serverSocket = new ServerSocket(SocketServerPORT);
        MainActivity.this.runOnUiThread(new Runnable() {

         @Override
         public void run() {
          info.setText("\n+I'm waiting here: "
            + serverSocket.getLocalPort()+"\n \n");
         }
        });

        while (true) {
            MulticastSocket sock = new MulticastSocket(12345);

            InetAddress addr = InetAddress.getByName("224.0.0.1");
            sock.joinGroup(addr);

            DatagramPacket packet;
            byte [] buffer= new byte[256];
            packet = new DatagramPacket(buffer, buffer.length);
            sock.receive(packet);
            String Message =  new String (packet.getData(),0,packet.getLength());

            replyip =packet.getSocketAddress().toString().substring(0, 13);
            message+=Message+replyip;

            sock.close();

         MainActivity.this.runOnUiThread(new Runnable() {

          @Override
          public void run() {
           msg.setText(message);
          }
         });



        SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(replyip, count);

       if(i==0 )
       {
        socketServerReplyThread.run();

       }

       if(j==0){

           socketServerReplyThread.run();

       }


        }
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }

     }

     private class SocketServerReplyThread extends Thread {



      String ips;

      SocketServerReplyThread(String ip, int c) {


       ips=ip;
      }

      @Override
      public void run() {




       try {



                    Socket s=new Socket(ips.toString(),12345);
                    DataOutputStream dos =new DataOutputStream(s.getOutputStream());
                    TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
                    String a = telephonyManager.getDeviceId();
                    dos.writeUTF(a);
                    dos.flush();
                    dos.close();
                    s.close();














        MainActivity.this.runOnUiThread(new Runnable() {

         @Override
         public void run() {
          msg.setText(message);
         }
        });

       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        message += "Something wrong! " + e.toString() + "\n";

       }

       MainActivity.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
         msg.setText(message);
        }
       });
      }

     }

     private String getIpAddress() {
      String ip = "";
      try {
       Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
         .getNetworkInterfaces();
       while (enumNetworkInterfaces.hasMoreElements()) {
        NetworkInterface networkInterface = enumNetworkInterfaces
          .nextElement();
        Enumeration<InetAddress> enumInetAddress = networkInterface
          .getInetAddresses();
        while (enumInetAddress.hasMoreElements()) {
         InetAddress inetAddress = enumInetAddress.nextElement();



         if (inetAddress.isSiteLocalAddress()) {

          ip += "SiteLocalAddress: " 
            + inetAddress.getHostAddress() + "\n";



         }

        }

       }

      } catch (SocketException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       ip += "Something Wrong! " + e.toString() + "\n";
      }

      return ip;
     }
}

3 个答案:

答案 0 :(得分:0)

当您按下后退按钮时,您的应用程序仍在内存中(使用“adb shell ps”验证)。再次启动时,会调用onCreate。现在你有两个消耗传入连接的SocketServerThread实例。

Android会因为您可能没有预料到的许多原因而破坏并重新创建活动,例如当您旋转屏幕时。因此,您必须小心将数据保存在活动中。

您应该将您的网络代码移出Activity并进入自己的类。使用单例或工厂模式来确保只有一个SocketServerThread。

答案 1 :(得分:0)

这里的问题是你的线程的run方法中的while(true)行。创建Activity的次数很多,正在创建新的Thread并在无限循环中执行它。如果您启动app&#34; n&#34;次,将创建n个线程。

  1. 请注意socketServerReplyThread.run(); call不会启动Thread。它是一个简单的方法调用。
  2. isAlive签入下面的代码是无用的,因为在它上面创建了一个新的Thread对象。

    线程t =新线程(新的SocketServerThread());         if(!t.isAlive()){             t.start();         }

  3. 要解决此问题,您可以使用一个标志来检查活动是否已销毁。并运行循环直到活动被破坏。这将确保一旦活动被销毁,Thread就没有任务。

    而(isDestroyed){ //做任务 }

    protected void onDestroy(){     super.onDestroy(); isDestroyed = true; }

  4. 我已经编辑了下面的代码,以确保不会创建多个线程。

    public class MainActivity extends Activity {
    
        TextView info, infoip, msg;
         String message = "";
         ServerSocket serverSocket;
         String s;
    
          String ipserver;
    
          String replyip;
           int i;
           int j;
    
    private boolean mIsDestroyed = false;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
    
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          info = (TextView) findViewById(R.id.info);
          infoip = (TextView) findViewById(R.id.infoip);
          msg = (TextView) findViewById(R.id.msg);
          i=0;
          j=1;
          infoip.setText(getIpAddress());
          WifiManager manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
          WifiInfo infor =manager.getConnectionInfo();
          String addr=infor.getMacAddress();
          this.s=addr;
    
    
        Thread t = new Thread (new SocketServerThread());
        if(!t.isAlive()){
        t.start();
        }
    
    
         }
    
         @Override
         protected void onRestart(){
    
    
         }
    
    
         @Override
         protected void onDestroy() {
          super.onDestroy();
    mIsDestroyed = true;
         i=1;
         j=0;
    
    
          if (serverSocket != null) {
           try {
            serverSocket.close();
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }
          }
         }
    
         private class SocketServerThread extends Thread {
    
          static final int SocketServerPORT = 7000;
          int count = 0;
    
          @Override
          public void run() {
           try {
            serverSocket = new ServerSocket(SocketServerPORT);
            MainActivity.this.runOnUiThread(new Runnable() {
    
             @Override
             public void run() {
              info.setText("\n+I'm waiting here: "
                + serverSocket.getLocalPort()+"\n \n");
             }
            });
    
            while (mIsDestroyed == false) {
                MulticastSocket sock = new MulticastSocket(12345);
    
                InetAddress addr = InetAddress.getByName("224.0.0.1");
                sock.joinGroup(addr);
    
                DatagramPacket packet;
                byte [] buffer= new byte[256];
                packet = new DatagramPacket(buffer, buffer.length);
                sock.receive(packet);
                String Message =  new String (packet.getData(),0,packet.getLength());
    
                replyip =packet.getSocketAddress().toString().substring(0, 13);
                message+=Message+replyip;
    
                sock.close();
    
             MainActivity.this.runOnUiThread(new Runnable() {
    
              @Override
              public void run() {
               msg.setText(message);
              }
             });
    
    
    
            SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(replyip, count);
    
           if(i==0 )
           {
            socketServerReplyThread.run();
    
           }
    
           if(j==0){
    
               socketServerReplyThread.run();
    
           }
    
    
            }
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }
          }
    
         }
    
         private class SocketServerReplyThread extends Thread {
    
    
    
          String ips;
    
          SocketServerReplyThread(String ip, int c) {
    
    
           ips=ip;
          }
    
          @Override
          public void run() {
    
    
    
    
           try {
    
    
    
                        Socket s=new Socket(ips.toString(),12345);
                        DataOutputStream dos =new DataOutputStream(s.getOutputStream());
                        TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
                        String a = telephonyManager.getDeviceId();
                        dos.writeUTF(a);
                        dos.flush();
                        dos.close();
                        s.close();
    
    
    
    
    
    
    
    
    
    
    
    
    
    
            MainActivity.this.runOnUiThread(new Runnable() {
    
             @Override
             public void run() {
              msg.setText(message);
             }
            });
    
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            message += "Something wrong! " + e.toString() + "\n";
    
           }
    
           MainActivity.this.runOnUiThread(new Runnable() {
    
            @Override
            public void run() {
             msg.setText(message);
            }
           });
          }
    
         }
    
         private String getIpAddress() {
          String ip = "";
          try {
           Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
             .getNetworkInterfaces();
           while (enumNetworkInterfaces.hasMoreElements()) {
            NetworkInterface networkInterface = enumNetworkInterfaces
              .nextElement();
            Enumeration<InetAddress> enumInetAddress = networkInterface
              .getInetAddresses();
            while (enumInetAddress.hasMoreElements()) {
             InetAddress inetAddress = enumInetAddress.nextElement();
    
    
    
             if (inetAddress.isSiteLocalAddress()) {
    
              ip += "SiteLocalAddress: " 
                + inetAddress.getHostAddress() + "\n";
    
    
    
             }
    
            }
    
           }
    
          } catch (SocketException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
           ip += "Something Wrong! " + e.toString() + "\n";
          }
    
          return ip;
         }
    }
    

答案 2 :(得分:0)

尝试使用Singleton模式,如下所述:

    public class MySingleton implements Runnable {
        private static MySingleton sInstance;
        private boolean mIsThreadStarted = false;

        // Use this method to access object of this class. Only single object of
        // this class will be created and thread will be started only once.
        public static synchronized MySingleton getInstance() {
            if (sInstance == null) {
                sInstance = new MySingleton();
            }
            return sInstance;
        }

        private MySingleton() {
            // Remove below call if you want start it later.
            startThread();
        }
  // Call this method whenever thread is to be started.  
        public void startThread() {
            if (mIsThreadStarted) {
                // Already started.
                return;
            }
            Thread t = new Thread(this);
            t.start();
            mIsThreadStarted = true;
        }

        @Override
        public void run() {
            // Your logic here, which should be running continuously.
            while (true) {
                // This loop will be running continuously till the app is running.
                // You will need to Implement Callback/Listener mechanism to pass
                // events to Activity.
            }
        }
    }