1

これは些細なことですが、私には意味がありません。Javaはポインタ/参照をパラメータとして渡すことはできませんが、read()関数にはaが渡さbuffer into which the data is readれ、intは。としてのみ返されthe total number of bytes read into the bufferます。

このデバイスから5つの個別のバイトを読み取ることを期待していますが、関数にバッファーを渡し、後でアクセスしようとすると、引き続きnull。関数からの戻り値を出力すると、int 5期待どおりのが得られます。しかし、実際にバッファに入れられたデータにアクセスするにはどうすればよいですか?

これがJavaDocsへのリンクです...。

編集:

これは、read関数への最初の呼び出しです。

public boolean onOptionsItemSelected( MenuItem item ) {
    switch( item.getItemId() ) {
    case R.id.connect:
        startActivityForResult( new Intent( this, DeviceList.class ), 1 );
        return true;
    case R.id.readTest:
        Log.i(TAG,  "Before write." );
        byte[] b = {'$'};
        for( int i = 0 ; i < 3 ; i++ ) {
            mService.write( b );
        }
        Log.i(TAG, "After write." );
        return true;

    case R.id.readData:
        byte[] c = mService.read( 5 );

        Toast.makeText(this, Integer.toString( mService.bytes ), Toast.LENGTH_LONG).show();
    default:
        return super.onContextItemSelected( item );
    }
}

この読み取り関数は、BluetoothServiceと呼ばれる私のクラスで宣言された関数であることに注意してください。このクラスには、InputStream読み取りを呼び出すConnectedThreadと呼ばれる別のクラスが含まれています...

これが私の読み取り機能です。

public byte[] read( int length ) {
    Log.i( TAG, "Inside read." );
    ConnectedThread r;
    buffer = null;
    synchronized( this ) {
        if( mState != STATE_CONNECTED ) return null;
        r = mConnectedThread;
    }
    Log.i(TAG,  "Before run." );
    r.run( length );
    Log.i( TAG, "After run." );
    Log.i( TAG, Integer.toString( bytes ) );
    return buffer;

}

そして、これがConnectedThreadクラスで、read自体を呼び出します。

/**
 * This thread runs during a connection with a remote device.
 * It handles all incoming and outgoing transmissions.
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket, String socketType) {
        Log.d(TAG, "create ConnectedThread: " + socketType);
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the BluetoothSocket input and output streams
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "temp sockets not created", e);
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run(int length) {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];


        // Keep listening to the InputStream while connected
        //while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer, 0, length);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                // Start the service over to restart listening mode
                BluetoothService.this.start();
                //break;
            }
       // }
            Log.i(TAG, "MADE IT HERE" );
    }

    /**
     * Write to the connected OutStream.
     * @param buffer  The bytes to write
     */
    public void write(byte[] buffer) {
        try {
            mmOutStream.write(buffer);

            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(MainMenu.MESSAGE_WRITE, -1, -1, buffer)
                    .sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Exception during write", e);
        }
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}
4

3 に答える 3

3

Javaはポインタ/参照をパラメータとして渡すことができません

はい、できます。

このような根本的な誤解はあなたを非常に混乱させるでしょう...

使用されることになっている方法read(...)は次のようになります。

byte[] buffer = new byte[42];
int nosRead = is.read(buffer, 0, buffer.length);

バッファオブジェクトを割り当て、それをパラメータとしてreadメソッドに渡します。バイトが読み取られ、(この場合は)オフセットゼロからバッファにコピーされます。メソッド呼び出しが戻ると、実際に読み取られたバイト数が返されます...そしてバイトは呼び出し元が処理できるようにバッファーにあります。

ご覧のとおり、これはバイト配列参照をパラメーターとしてメソッドに渡すことに依存readしています。

于 2012-07-24T14:28:26.387 に答える
2

配列を初期化する必要があります。そうしないと、nullのままになります。

于 2012-07-24T14:20:31.723 に答える
1

おそらく、read()の呼び出しを適切にすることに混乱したCのバックグラウンドがあります。配列を返すか、ポインターへのポインターを使用して配列を作成する代わりに、read(byte [])およびread(byte [] b、int offset、int len)は、実際のバイト配列(後者の形式では、サイズが大きいか、引数リストのoffset+lenに等しい)。メソッドから値xが返されると仮定すると、offsetからoffset + x-1までの配列要素が配列で定義されます(-1が返された場合を除きます。これはEOFを示します)。

于 2012-07-24T14:24:52.620 に答える