Android片段在getview()上reutn null

时间:2017-06-08 14:40:16

标签: android websocket null fragment getview

我希望在存在来自websocket连接的onMessage回调事件时更新片段中的文本。 我的主要活动有那个

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) {
                }
            }   
        }
    }
}   

和Home Fragment

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 

文本永远不会再次更新。

1 个答案:

答案 0 :(得分: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课程所指向的内容不同,导致findFragmentByTag调用中返回null,因为您HomeFragment重新尝试请求已在您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
    }
}