方向更改后,Android Activity会获取错误的值

时间:2015-03-19 11:51:26

标签: java android android-fragments orientation-changes

我有一个奇怪的问题&我希望有人可以对此有所了解:

我正在构建一个需要建立WebRTC视频会议的基本Android应用程序。保持插座/会议/视频的方向变化。我创建了一个单例以维持连接&所有工作都很好,除了...在方向改变后,主要活动不正确地读取我的布尔值。

流程基本上是: 片段状态布尔值保存到onDestroyView()中的单例 在onCreateView()

中从单例加载的片段状态布尔值

片段中的值是正确的,但是当我尝试从主要活动中读取它们时,它们总是“假”。这是为什么?

另外,当我将它们作为参数传递时,它们是正确的。这是为什么?

(对于这两个问题,请参阅主要活动中的communicatorReady())

主要活动:

public class MainActivity extends Activity implements Communicator.OnEventListener{
    private Communicator communicator = null;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);  // Point to layout/main.xml

        // Add fragment to app
        communicator = new Communicator();
        if(savedInstanceState == null){
            getFragmentManager()
                    .beginTransaction()
                    .add(R.id.alContainer, communicator)
                    .commit();
        }
    }

    // Event listener
    public void communicatorReady(boolean communicatorReady, boolean communicatorConnected, boolean userConnected){
        // Also tried with a communicator.getCommunicatorReady() func, same incorrect result
        Log.i(TAG, "communicator.communicatorReady " + (communicatorReady ? "true" : "false"));  // Read from object, always false
        Log.i(TAG, "communicatorConnected " + (communicatorConnected ? "true" : "false"));   // Passed as parameter, correct value
    }
}

片段:

public class Communicator extends Fragment{
    // Communicator stuff
    private WebView webComm = null;
    private ServiceInfoEvent servInfo = null;
    public boolean communicatorReady = false;
    public boolean communicatorConnected = false;
    public boolean userConnected = false;

    // WebRTC stuff
    private LocalMedia localMedia = null;
    private Conference conference = null;

    public CommunicatorEngine communicatorEngine = null;

    // Event messages
    OnEventListener eventListener;
    public interface OnEventListener{
        public void communicatorReady(boolean communicatorReady, boolean communicatorConnected, boolean userConnected);
    }

    @Override
    public void onAttach(Activity activity){
        super.onAttach(activity);

        // Check event listener interface is implemented
        try{
            eventListener = (OnEventListener) activity;
        }
        catch(ClassCastException ex){
            throw new ClassCastException(activity.toString() + " must implement OnEventListener");
        }
    }

    // Setup the view & comms on fragment creation
    public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.alview, parentViewGroup, false);

        communicatorEngine = CommunicatorEngine.getInstance(getActivity());
        webComm = communicatorEngine.getWebComm();

        if(!communicatorEngine.isWebCommInitialised()){
            // Comm webview not initialised, do the initial setup
            RelativeLayout.LayoutParams flp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            webComm.setLayoutParams(flp);
            webComm.getSettings().setJavaScriptEnabled(true);
            webComm.addJavascriptInterface(new ALCTranslator(getActivity()), "appJSInterface");
            webComm.loadUrl("file:///android_asset/communicator.html");
            webComm.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
            webComm.setBackgroundColor(Color.TRANSPARENT);

            communicatorEngine.setWebCommInitialised(true);
        }
        else{
            // Webview stuff has already run, restore previously saved items
            conference = communicatorEngine.getConference();
            String peerID = communicatorEngine.getConferencePeerId();
            communicatorReady = communicatorEngine.isCommunicatorReady();
            communicatorConnected = communicatorEngine.isCommunicatorConnected();
            userConnected = communicatorEngine.isUserConnected();

            // Add remote video to our view if there is an active conference
            if(conference != null && peerID != null){
                try{
                    RelativeLayout incomingStreamContainer = (RelativeLayout) rootView.findViewById(R.id.contIncomingStream);
                    View remoteVideoControl = (View) LinkExtensions.getRemoteVideoControl(conference.getLink(peerID));
                    localMedia = new LocalMedia(this);
                    localMedia.getLayoutManager().addRemoteVideoControl(peerID, remoteVideoControl);
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }

            // Inform the caller that the communicator is ready
            eventListener.communicatorReady(communicatorReady, communicatorConnected, userConnected);
        }

        // Add the webview to the current view
        RelativeLayout contCommunicator = (RelativeLayout) rootView.findViewById(R.id.contCommunicator);
        contCommunicator.addView(webComm);

        return rootView;
    }


    public void onDestroyView(){
        RelativeLayout container = (RelativeLayout) getView().findViewById(R.id.contCommunicator);
        container.removeView(webComm);

        // Save connection state info
        communicatorEngine.setCommunicatorReady(communicatorReady);
        communicatorEngine.setCommunicatorConnected(communicatorConnected);
        communicatorEngine.setUserConnected(userConnected);

        super.onDestroyView();
    }
}

的Singleton:

public final class CommunicatorEngine{
    private static CommunicatorEngine instance = null;

    // Communicator stuff
    private WebView webALC = null;
    private boolean webALCInitialised = false;
    private boolean communicatorReady = false;
    private boolean communicatorConnected = false;
    private boolean userConnected = false;
    private Conference conference = null;
    private String conferencePeerId = null;

    private CommunicatorEngine(Context context){
        // Create communicator webview
        webALC = new WebView(context);
        webALCInitialised = false;
    }

    public static synchronized CommunicatorEngine getInstance(Context context){
        if(instance == null){
            // Use app context to prevent memory leaks
            instance = new CommunicatorEngine(context.getApplicationContext());
        }

        return instance;
    }

    public WebView getWebALC() {return webALC;}
    public boolean isWebALCInitialised() {return webALCInitialised;}
    public void setWebALCInitialised(boolean isInitialised) {webALCInitialised = isInitialised;}

    public boolean isCommunicatorReady(){return communicatorReady;}
    public void setCommunicatorReady(boolean isReady){communicatorReady = isReady;}

    public boolean isCommunicatorConnected(){return communicatorConnected;}
    public void setCommunicatorConnected(boolean isConnected){communicatorConnected = isConnected;}

    public boolean isUserConnected(){return userConnected;}
    public void setUserConnected(boolean isConnected){userConnected = isConnected;}

    public Conference getConference() {return conference;}
    public void setConference(Conference conferenceToSave) {conference = conferenceToSave;}
    public String getConferencePeerId() {return conferencePeerId;}
    public void setConferencePeerId(String peerIdToSave) {conferencePeerId = peerIdToSave;}
}

修改

添加日志消息会产生以下结果:

Fragment﹕ ********* onDestroyView() *********
Fragment﹕ Saved communicatorReady true
Fragment﹕ Saved communicatorConnected true
Fragment﹕ Saved userConnected false
Fragment﹕ ********* onCreateView() *********
Fragment﹕ Loaded communicatorReady true
Fragment﹕ Loaded communicatorConnected true
Fragment﹕ Loaded userConnected false

Activity﹕ communicatorReady Event
Activity﹕ *******************
Activity﹕ Passed as parameter: communicatorReady true
Activity﹕ Passed as parameter: communicatorConnected true
Activity﹕ Passed as parameter: userConnected false
Activity﹕ ********************************
Activity﹕ communicator.communicatorReady false
Activity﹕ communicator.communicatorConnected false
Activity﹕ communicator.userConnected false

编辑2

如果我将通信器设置为静态,问题就会消失:

private static Communicator communicator;

我猜这是一个被查询错误对象的问题。

0 个答案:

没有答案