“此处理程序类应为静态或可能发生泄漏”的解决方案是什么?

时间:2019-09-13 15:37:21

标签: android bluetooth

我正在一个蓝牙通信项目中,我需要在设备之间传输数据。收到 InputStream 后,我使用以下代码将数据从工作线程传递到UI线程:-< / p>

// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = handler.obtainMessage(MessageConstants.MESSAGE_READ,numBytes, -1,mmBuffer);
readMsg.sendToTarget();

下面是我的处理程序类:-

public Handler mHandler = new Handler() {
    public synchronized void handleMessage(Message msg) {
        byte[] readBuf=(byte[])msg.obj;
        String readMsg=new String(readBuf,0,msg.arg1);
        TextView textView=findViewById(R.id.textview);
        textView.setText(readMsg);
    }
}

但这显示以下警告:

  

此Handler类应该是静态的,否则可能会发生泄漏(匿名android.os.Handler)。

我尝试将类设为静态,但随后出现以下错误:-

  

不能从静态上下文中引用非静态方法findViewById(int)。

我应该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:0)

public MyHandler mHandler;

public static class MyHandler extends Handler {

    WeakReference<TextView> mTextViewReference;

    public MyHandler(TextView textView) {
        mTextViewReference = new WeakReference<TextView>(textView);
    }

    public synchronized void handleMessage(Message msg) {
        byte[] readBuf=(byte[])msg.obj;
        String readMsg = new String(readBuf,0,msg.arg1);
        TextView textView = mTextViewReference.get();
        if(textView != null) {
            textView.setText(readMsg);
        };
    }

    public void clear() {
        mTextViewReference.clear();
        mTextViewReference = null;
    }
}

protected void onCreate(final Bundle savedInstanceState) {
    ....
    mHandler = new MyHandler(findViewById(R.id.textView));
    ....
}

@Override
public void onDestroy() {
    if(mHandler != null) {
        mHandler.clear();
        mHandler = null;
    }
    super.onDestroy();
}

编辑

如果您只想更新一个TextView,则上面的修复效果很好。但是,通常,您需要采取更多的操作并更新更多的内容(不仅是一个TextView)。因此,我认为您可以创建一个Interface,它在每次收到消息时都会被调用。像这样:

public class MyActivity extends Activity {

    public MyHandler mHandler;

    protected final void onCreate(final Bundle savedInstanceState) {
        //....
        mHandler = new MyHandler(new MyHandler.OnMessageReceivedListener() {
            @Override
            public void handleMessage(final String message) {
                // Update the views as you with
            }
        });

        //....
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.clear();
    }

    public static class MyHandler extends Handler {

        WeakReference<OnMessageReceivedListener> mListenerReference;

        public MyHandler(OnMessageReceivedListener listener) {
            mListenerReference = new WeakReference<>(listener);
        }

        public synchronized void handleMessage(Message msg) {
            byte[] readBuf=(byte[])msg.obj;
            String readMsg = new String(readBuf,0,msg.arg1);
            OnMessageReceivedListener listener = mListenerReference.get();
            if(listener != null) {
                listener.handleMessage(readMsg);
            };
        }

        public void clear() {
            mListenerReference.clear();
        }

        public interface OnMessageReceivedListener {
            void handleMessage(String message);
        }
    }
}

答案 1 :(得分:0)

您在handleMessage部门的工作人员并不繁琐,因此无需扩展Handler使其简单而轻巧;只需添加一个回调即可。在您的活动/片段中创建一个回调:

private class MessageCallback implements Handler.Callback {

        @Override
        public boolean handleMessage(@NonNull Message message) {

            // Here you can call any UI component you want

            TextView textView=findViewById(R.id.textview);
            textView.setText(readMsg);
            return true;
        }
    }

然后将其称为:

Handler handler = new Handler(getMainLooper(), new MessageCallback());
Message readMsg = handler.obtainMessage(what, arg1, arg2, object);
readMsg.sendToTarget();