2017-06-08 13 views
-1

webSocket接続からのonMessageコールバックイベントが存在する場合、フラグメント内のテキストを更新したいと考えています。 私の主な活動はgetview()のAndroidフラグメントreutn null

public class MainActivity extends AppCompatActivity{ 

private static WebSocketConnection mConnection = new WebSocketConnection(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.intent_root_activity); 

     if(savedInstanceState == null){ 
       frag_Home = new HomeFragment(); 
       fragmentManager.beginTransaction().add(R.id.fragmentContent, frag_Home, getString(R.string.TAG_HOME)).commit(); 
      }else{ 
       if(fragmentManager.findFragmentByTag(getString(R.string.TAG_HOME)) == null){ 
        frag_Home = new HomeFragment(); 
        fragmentManager.beginTransaction().add(R.id.fragmentContent, frag_Home, getString(R.string.TAG_HOME)).commit(); 
       } 

     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     // Start Connection 
     Connect(ipAdress); 
     Log.i("ROOT ACTIVITY", "onResume"); 
    } 


    // Function callback events 
    private void Connect(String ipAddress){ 

    final String wsuri = "ws://" + ipAddress + ":" + port; 

     try { 
      // Handle Websocket Event 
      mConnection.connect(wsuri, new WebSocketHandler() { 

       @Override 
       public void onOpen() { 
        Log.d("WIFI", "onOpen: Conneced to "+ wsuri); 
       } 



       @Override 
       public void onTextMessage(String payload) { 
        HomeFragment home = (HomeFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.TAG_HOME)); 
        ((TextView)home.getView().findViewById(R.id.txtMsg)).setText(payload); 
       } 

       Override 
       public void onClose(int code, String reason) { 
       } 
      } 
     } 
    } 
} 

と家庭断片

public class HomeFragment extends Fragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
      View view = inflater.inflate(R.layout.fragment_home, container, false); 
      txtVw  = (TextView)  view.findViewById(R.id.txtMsg); 

     return view; 
    } 

} 

は、すべてのテキストが正しく更新されますが、メッセージを受信したとき、私は自分の携帯電話を回転させたときに、私は

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View test.test.com.test.HomeFragment.getView()' on a null object reference 

とGET正常に動作することを持っていますテキストは決して再び更新されません。

+0

なぜ設定しますか?テキストが正しく更新されます。画面を回転させるとビューのIDが緩くなります –

答えて

0

短い答えは

これはあなたの活動のマニフェストにandroid:configChanges="orientation"を追加することで固定することができますが、あなたはオリエンテーションの変更を処理するために、独自に残っているので、これはUIのバグにつながることができます。

ロング回答

mConnection.connect(wsuri, new WebSocketHandler() { 

      @Override 
      public void onOpen() { 
       Log.d("WIFI", "onOpen: Conneced to "+ wsuri); 
      } 

この内部匿名クラスWebSocketHandlerは、作成時点であなたのMainActivityの現在のインスタンスへの暗黙の参照が含まれていますが、そのインスタンスは、姿勢の変化にAndroidのシステムでゴミ箱に移動されます。だからオリエンテーション変更後に見ているのは、あなたのWebSocketHandlerクラスが指しているものとは別のインスタンスであり、あなたが要求しようとしているHomeFragmentがすでに古いものでクリーンアップされているため、findFragmentByTagコールで返されたヌルMainActivityのインスタンスです。また、WebSocketHandlerが古いインスタンスMainActivityがGCされないため、メモリリークが発生します。

私がお勧めするものは、websocket接続を処理する全く別のクラスを持ち、Activityの内部クラスではありません。または、android:configChanges="orientation"を使用して、向きの変更を正しく処理することができます。

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    // Checks the orientation of the screen 
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 
     //handle the orientation change, ex change/rearrange fragments 
    } 
} 
+0

しかし、デバイスを回転させると接続が緩んでいません。私は静的なのでsemmsは同じinstaceを持っています。静的な接続を削除すると、回転時に接続が失われる –

+0

静的であるためMainActivityへの暗黙の参照がWebSocketHandlerの作成時点で保持されるため、接続が切断されるか、クリーンアップされます。したがって、回転するとWebSocketHandlerは現在Screeenに表示されている新しいMainActivityインスタンスを指していません。 WebSocketHandlerが指しているMainActivityインスタンスは古いインスタンスで、クリーンアップのために保留中ですが、WebSocketHandlerが暗黙的に指しているため、システムはクリーンアップできません。 MainActivityのonDestroyにログを追加して、回転時に破棄されることを確認してください。 –

+0

ok。私は理解しています..与えられた解決策。 onCreateイベントでsetRetainstance(true)を使用して、webSocketハンドラを非UIフラグメントに配置しました。どうもありがとう –

関連する問題