有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么当我通过NavController返回时,我的片段*有时*是空白的。navigateUp()?

当通过navigateUp()返回IpFragment时,它有时是空的,这时它应该显示几个简单的文本视图。有时渲染正确,但如果失败,唯一的错误似乎是无关的

返回时显示为空白的片段:

public class IpFragment extends Fragment implements ...{
    private static final String TAG = "IpFragment";

    private NavController navController;
    private Context context;
    private TextView tvIp;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        navController = NavHostFragment.findNavController(this);
        View v = inflater.inflate(R.layout.fragment_ip, container, false);
        context = v.getContext();
        return v;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d(TAG, "onViewCreated");

        ConnectivitySingleton.getInstance().registerCallback(this);

        tvIp = view.findViewById(R.id.tvIp);
        tvIp.setText(getDeviceIp());
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        ConnectivitySingleton.getInstance().unregisterCallback(this);
    }

    ...
}

我们返回的片段:

public class InterviewFragment extends Fragment implements ConnectionCallback, StreamStatusCallback, TextureView.SurfaceTextureListener, SpeakCallback {
    private static final String TAG = "InterviewFragment";

    private NavController navController;
    private AutoFitDrawableView autoFitDrawableView;
    private Context context;
    public boolean isStreaming;
    private MessageConnection messageConnection;

    private TextView tvQuestion;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
//        return super.onCreateView(inflater, container, savedInstanceState);
        navController = NavHostFragment.findNavController(this);
        View v = inflater.inflate(R.layout.fragment_interview, container, false);
        context = v.getContext();
        return v;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onViewCreated");
        super.onViewCreated(view, savedInstanceState);
        ConnectivitySingleton.getInstance().registerCallback(this);
        VisionSingleton.getInstance().registerCallback(this);
        SpeakSingleton.getInstance().registerCallback(this);

        autoFitDrawableView = view.findViewById(R.id.autofit);
        // need to set autoFitDrawableView's display size / rotation
        int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation();
        autoFitDrawableView.setPreviewSizeAndRotation(800, 600, rotation); // w 800 h 600
        // set listener to stream frames
        autoFitDrawableView.setSurfaceTextureListenerForPreview(this);

        tvQuestion = view.findViewById(R.id.question);
    }

    @Override
    public void onDestroyView() {
        Log.d(TAG, "onDestroyView");
        super.onDestroyView();
        ConnectivitySingleton.getInstance().unregisterCallback(this);
        VisionSingleton.getInstance().unregisterCallback(this);
        SpeakSingleton.getInstance().unregisterCallback(this);
    }

    @Override
    public void onConnected() {
    }

    @Override
    public void onDisconnected() {
        navController.navigateUp();
    }

    @Override
    /**
     * Passes surfaceTexture to VisionSingleton once ST is available. VisionSingleton then sets up
     * DTS camera to stream to surfaceTexture.
     */
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        Log.d(TAG, "onSurfaceTextureAvailable");
        VisionSingleton.getInstance().initPreview(surfaceTexture);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) { }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        Log.d(TAG, "onSurfaceTextureDestroyed");
        VisionSingleton.getInstance().stopPreview();
        return false;
    }

    @Override
    /**
     * If a 'vision start' command has been received, then surfaceTexture's frame should be sent to
     * the phone app via messageConnection.
     */
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
        if(isStreaming) {
            try {
                int tvWidth = autoFitDrawableView.getPreview().getWidth();
                int tvHeight = autoFitDrawableView.getPreview().getHeight();

                // Get bitmap from TextureView
                Bitmap bm = Bitmap.createBitmap(tvWidth, tvHeight, Bitmap.Config.ARGB_8888);
                autoFitDrawableView.getPreview().getBitmap(bm);

                // Compress via JPG
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                bm.compress(Bitmap.CompressFormat.JPEG, 50, os);
                byte[] byteArray = os.toByteArray();

                Log.d(TAG, "Byte size: " + byteArray.length);
                if (byteArray.length > 1000000) {
                    Log.w(TAG, "Byte size is > 1 MB! Exceeds max sending size.");
                } else {
                    messageConnection.sendMessage(new BufferMessage(byteArray));
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
            }
        }

    }

    @Override
    public void onStartStream(final MessageConnection messageConnection) {
        Log.d(TAG, "onStartStream");
        isStreaming = true;
        this.messageConnection = messageConnection;
    }

    @Override
    public void onStopStream() {
        Log.d(TAG, "onStopStream");
        isStreaming = false;
    }

    @Override
    public void onSpeakCommandReceived(String question) {
        tvQuestion.setText(question);
    }
}

有时在InterviewFragment中,我会发现这个错误,当时它不会破坏任何东西,但稍后返回到IpFragment时,它会显示为空白

08-07 22:45:54.921 5196-5275/edu.unc.etlab.robojloomo W/MessageListener: Exception occured during command launch
    安卓.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at 安卓.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
        at 安卓.view.ViewRootImpl.requestLayout(ViewRootImpl.java:874)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:3172)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
        at 安卓.view.View.requestLayout(View.java:17476)
        at 安卓.widget.TextView.checkForRelayout(TextView.java:6865)
        at 安卓.widget.TextView.setText(TextView.java:4057)
        at 安卓.widget.TextView.setText(TextView.java:3915)
        at 安卓.widget.TextView.setText(TextView.java:3890)
        at edu.unc.etlab.robojloomo.InterviewFragment.onSpeakCommandReceived(InterviewFragment.java:168)
        at edu.unc.etlab.robojloomo.loomo_services.SpeakSingleton.speak(SpeakSingleton.java:69)
        at edu.unc.etlab.robojloomo.listeners.SpeakCommand.execute(SpeakCommand.java:14)
        at edu.unc.etlab.robojloomo.listeners.MessageListener.onMessageReceived(MessageListener.java:85)
        at com.segway.robot.sdk.connectivity.RobotMessageConnection.handleMessage(RobotMessageConnection.java:219)
        at 安卓.os.Handler.dispatchMessage(Handler.java:98)
        at 安卓.os.Looper.loop(Looper.java:135)
        at 安卓.os.HandlerThread.run(HandlerThread.java:61)

在InterviewFragment中设置textView的文本时会发生此错误:

    public void onSpeakCommandReceived(String question) {
        tvQuestion.setText(question);
    }

共 (1) 个答案

  1. # 1 楼答案

    好的,在发布这个问题后,我很快就解决了它。我参考了这篇帖子来修复我遇到的错误:Android "Only the original thread that created a view hierarchy can touch its views."。我把onSpeakCommandReceived()改为:

        public void onSpeakCommandReceived(final String question) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvQuestion.setText(question);
                }
            });
        }
    

    仍然不确定这个错误是如何导致下一个屏幕空白的,因为它们发生在不同的时间,但现在这个错误已经修复,一切似乎都正常