2012-03-16 14 views
2

私はJavaとAndroid開発の両方にとても新しいので、サーバーにメッセージを送信してサーバーからメッセージを受け取るようにAndroidクライアントを設計しています。それはいくつかの機能を実行するだけで、最初にサーバーにその初期状態を照会し、その状態を使用してボタンを更新し、充電器が充電中かどうかを示す充電記号を出します。私はすべての通信コードを持っているとスレッドが十分にメッセージを送信し、受信しているようだが、スレッドの外の変数は更新されていない、と私はサーバー接続をシャットダウンした場合、クライアントは、サーバーがまだそこにあるかのように。誰も私の問題を解決するために、いくつかのアドバイスをくれますか?ソケットクライアント+スレッド+ Android +接続ステータス

package charger.app; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.StrictMode; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageButton; 
import android.widget.Toast; 


public class ChargeTabActivity extends Activity { 

String serverIp = "192.168.6.120"; //server Ip address 
private static String preqon = "control:Charger:1\r\n"; //sets connection to turn charger on 
private static String preqoff = "control:Charger:0\r\n"; //Turn charger off 
public boolean connected = false; //connection 

//set up buttons 
private ImageButton chargeOnOff; 
private ImageButton connectButton; 

//Set it so that Client Functions can be accessed from main program 
ClientFunctions functions = new ClientFunctions(); 



@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //initialize UI 
    setContentView(R.layout.main); 

    //declare buttons for listeners, and display changes   
    connectButton = (ImageButton)findViewById(R.id.connectButton);  
     connectButton.setOnClickListener(connectButtonListener);  
    chargeOnOff = (ImageButton)findViewById(R.id.chargeOnOff); 
     chargeOnOff.setOnClickListener(chargeOnOffListener); 
    Button chargeStatus = (Button)findViewById(R.id.chargeStatus); 



    ////set up strict mode off///// 
     StrictMode.ThreadPolicy policy = new StrictMode. 
       ThreadPolicy.Builder().permitAll().build(); 
       StrictMode.setThreadPolicy(policy); 


} 



/*Listens to see if the connect button is pressed, if it is connected it will 
* display connected, else it will try and connect*/ 
private OnClickListener connectButtonListener = new OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     if (connected) 
     { 
      toast("I am connected"); 
     } 
     else 
     { 
      toast("I am not connected"); 
     } 
    } 
}; 


/*Listens to see if the Charge on Off Button is pressed, if it is charging it will 
* send a request to charge, else it will send a request to stop the charge*/ 
private OnClickListener chargeOnOffListener = new OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     //ask server 
     try { 
      functions.updateStatus(); //updates the charger status 
     } catch (IOException e) { 
      Log.e("Client","Trouble querying",e); 
      e.printStackTrace(); 
     } 

     //send message to turn server on or off 
     if (functions.chargeStatNumber != 0) 
     { 
      try { 
       functions.sendMessage(preqoff); 
       chargeOnOff.setImageResource(R.drawable.charge_on); 
       toast("Turning Charger off"); 
      } catch (UnsupportedEncodingException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


     }//end if 


     else 
     { 
      try { 
       functions.sendMessage(preqon); 
       chargeOnOff.setImageResource(R.drawable.charge_off); 
       toast("Turning Charger on"); 

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


     } //end else 

     Log.d("ClientActivity", "Charge Button hit"); 


     //ask server about its status 
     try { 
      functions.updateStatus(); //updates the charger status 
     } catch (IOException e) { 
      Log.e("Client","Trouble querying",e); 
      e.printStackTrace(); 
     } 

    } 
}; 


/////When Application Starts 
@Override 
public void onStart() 
{ 
    super.onStart(); 

    Thread cThread = new Thread(new serverThread()); //Starts the thread that initiates communications 
    cThread.start(); 
}; 

////////On Pause//////This is when a user makes another app, the center point of attention 
@Override 
public void onPause() { 
    super.onPause(); 
    functions.closeConnection(); 

}; 

//////On Resume/////This is used for when an app exits, and then the user brings it back 
@Override 
public void onResume() { 
    super.onResume(); 


}; 

//////On Destroy////////// 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
    functions.closeConnection(); 

}; 



//toast messages 
public void toast(String toastMessage) 
{ 
    Toast.makeText(DelphiChargeTabActivity.this, toastMessage, 
      Toast.LENGTH_LONG).show(); 
}; 



//Thread to run and receive network connections 

public class serverThread implements Runnable 
{ 
    public boolean connected = false; //connection 
    public void run() //runs the thread 
    { 

     try 
     { 
      functions.connectToServer(serverIp); //connects to server 
      connected = true; 

      while (connected) 
      { 
       try 
       { 
        connectButton.setImageResource(R.drawable.blue_car); 
        functions.getStreams(); //establish stream connections 
        functions. updateStatus(); //updates the status of the server 
        //checkChangeChargeButton(); //sets initial state for charge button 



        try 
        { 
         Thread.sleep(2500); 
        } 
          catch (InterruptedException interruptedException) 
          { 
          functions.displayMessage("\nThread exception"); 
          } // end catch 

       } 
        catch (IOException e) 
        { 
         Log.e("Client","Trouble Getting Streams",e); 

        } 



      }//end while 
     }//end try 
      catch (Exception e) 
      { 
       Log.e("Client", "Error Connecting", e); 
       connected = false; 
       connectButton.setImageResource(R.drawable.red_car); 

      } 
    }; //end run 
}; //end serverThread 

public void checkChangeChargeButton() 
{ 

    if (functions.chargeStatNumber != 0) 
    { 
     chargeOnOff.setImageResource(R.drawable.charge_on); 
    } 
    else 
    { 
     chargeOnOff.setImageResource(R.drawable.charge_off); 
    } 

}; 



} //This is the Activity close bracket 

これは私の機能方法あなたが別のスレッドからUIを更新することはできません

package charger.app; 
import java.io.BufferedWriter; 
import java.io.DataInputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.io.UnsupportedEncodingException; 
import java.net.InetAddress; 
import java.net.Socket; 

import android.util.Log; 


public class ClientFunctions 
{ 

private String message; 
private String server; 
public Socket sock; 
private PrintWriter writer; 
private DataInputStream inStream; 
public Boolean connected; 
private String encode = "UTF8"; 
public byte[] chargerstat; 
public int chargeStatNumber; //Used to set the array byte 15 to an int 


//inquires server for status of charge 
public void updateStatus() throws IOException 
{ 
    //Prompt user for server command 
    System.out.println("Sending request for Charger status data."); 
     String serverMessage = "meas:Charger?\r\n"; 

    // send the message 
     sendMessage("meas:Charger?\r\n"); 
     System.out.println(); 
     displayMessage(serverMessage + "sent"); 

    // now receive the message 
    receiveMessage(); 
     displayMessage("Receive complete"); 


}; 


public void connectToServer(String serverIp) throws IOException //Server IP is sent in main app as String "serverIp" 
{ 
    //set server IP 

    //display logcat trying to connect 
    displayMessage("\nTrying to Connect"); 
    //Start Socket Connection 
    sock = new Socket(InetAddress.getByName(serverIp), 18088); 
    //Display connected 
    displayMessage("\nConnected to: " + 
      sock.getInetAddress().getHostName()); 



}; 

public void getStreams() throws IOException 
{ 
    //Set up PrintWriter 
    writer = new PrintWriter(new BufferedWriter(new   OutputStreamWriter(sock.getOutputStream())),true); 
    writer.flush(); 
    //Set Up I 
    inStream = new DataInputStream(sock.getInputStream()); 
    //display Message Got I/O 
    displayMessage("\nGot IO Streams"); 

}; 

public void sendMessage(final String serverMessage) throws UnsupportedEncodingException 
{ 


    //set variable for message 
    message = serverMessage; 
    //sends message 
    writer.printf("%s", message); 
    writer.flush(); 
    //display message sent 
    displayMessage("\nsent" /*+ serverMessage*/); 




}; 

public static int getInt(byte[] array, int offset) 
    { 
    return 
     ((array[offset+3] & 0xff) << 24) | 
     ((array[offset+2] & 0xff) << 16) | 
     ((array[offset+1] & 0xff) << 8) | 
     (array[offset] & 0xff); 
    } 


public void receiveMessage() throws IOException 
{ 
    { 
     int c=0; 
     int i;   
     int seqcountval; 

     chargerstat = new byte[96]; 
     i=0; 
     while(i < 96) 
     { 
      try 
      { 
       c = inStream.read(); 
       chargerstat[i] = (byte)c; 
      } 
      catch (IOException ioException) 
      { 
       ioException.printStackTrace(); 
      } // end catch 
// uncomment this to see each byte   
      //displayMessage(":" + i + " " + chargerstat[i]); 
      i++; 
     } 

     seqcountval = getInt(chargerstat, 76); 
     displayMessage("SeqCntr = " + seqcountval); 
     chargeStatNumber = chargerstat[15]; 

    }; 
}; 

public void closeConnection() 
{ 
    //closes connections 
    displayMessage("\n\nClosing Connection"); 

    try 
    { 
     writer.close(); 
     inStream.close(); 
     sock.close(); 


    } 
    catch (IOException ioException) 
     { 
     ioException.printStackTrace(); 
     } // end catch 


}; 



public void displayMessage(final String messageToDisplay) 
    { 

     new Runnable() 
     { 
      public void run() // updates displayArea 
      { 
       //change to log.d for android 
       System.out.println(messageToDisplay); 
      } // end method run 
     }; // end anonymous inner class 

    } // end method displayMessage 





};  
+0

として、アンドロイド4.0の後、UIスレッドで使用することはできませんか?なぜクライアントはサーバーへの接続を維持しているとしますか(表示は何ですか)。 – Sid

+0

申し訳ありませんが、私の接続変数と私のchargerstat [15]は、常にスレッド外で更新されているようではなく、接続が片側で切断されたときに接続状態を終了する問題があります。 –

+0

接続されたInside ServerThreadは、ChargerActivityとは異なる接続です。彼らは決して関連していません。 – Sid

答えて

1

ような何かを行うことができ、情報を共有することがはるかに容易にし、あなたものに該当すると思われるでしょうもう一度やろうとする。 AsyncTask

AsyncTaskを使って

はあなたのユーザー インターフェイス上の非同期の作業を実行することができます。ワーカースレッドでブロッキング操作を実行し、 は、 スレッドやハンドラを自分で処理する必要なく、結果をUIスレッドにパブリッシュします。

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html

ChargerActivityであなたの「接続」変数は、それゆえChargerActivityの接続は、スレッドから更新されることはありませんあなたのServerThreadとは異なっています。

+0

ありがとう、私はそれを試してみましょう。 –

0

ためのコードです。メインスレッドのUIを更新する必要があります。あなたが別のスレッドからUIを更新したい場合は、あなたがあなたの代わりにスレッドのAsyncTaskを使用していないのはなぜこの

public void changeButtonImage(){ 
    runOnUiThread(new Runnable(){ 

     @Override 
     public void run() { 
      connectButton.setImageResource(R.drawable.blue_car); 
     }}); 
} 
1

ソケット機能は、お使いの接続funcitonと糸の外側の変数が更新されていないのsendMessage