3. Android侧创建客户端应用

任务目标

在Android侧创建一个客户端应用,通过本地Socket与QNX侧服务建立连接,完成一次数据请求/响应交换。本案例聚焦Android客户端实现,QNX服务端地址与端口作为已知配置项。

环境与依赖

  • Android Studio(API 21+)
  • QNX侧服务监听 10.0.2.2:5555(模拟器访问宿主机)或局域网内QNX设备IP
  • 无需第三方库,使用 java.net.Socket

关键完整代码

以下为Android客户端核心实现,包含网络操作、UI触发与数据接收。使用AsyncTask(或替代方案)避免在主线程执行网络操作。

// MainActivity.java
public class MainActivity extends AppCompatActivity {
    private TextView tvResult;
    private EditText etInput;
    private static final String SERVER_IP = "10.0.2.2"; // QNX服务端地址
    private static final int SERVER_PORT = 5555;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvResult = findViewById(R.id.tv_result);
        etInput = findViewById(R.id.et_input);
        findViewById(R.id.btn_send).setOnClickListener(v -> new SocketTask().execute(etInput.getText().toString()));
    }

    private class SocketTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            String request = params[0];
            try (Socket socket = new Socket(SERVER_IP, SERVER_PORT);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
                out.println(request);
                return in.readLine(); // 阻塞等待QNX响应
            } catch (IOException e) {
                return "ERROR: " + e.getMessage();
            }
        }

        @Override
        protected void onPostExecute(String result) {
            tvResult.setText(result);
        }
    }
}

对应布局文件 activity_main.xml 关键部分:

<EditText android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入请求内容"/>
<Button android:id="@+id/btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送"/>
<TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="响应将显示在此"/>

在 AndroidManifest.xml 中添加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>

运行与验证

  1. 在QNX侧启动服务端监听 0.0.0.0:5555,收到字符串后返回带前缀的响应(如 "ECHO: " + 原数据)。
  2. 将Android应用部署到模拟器或真机(确保网络可达QNX设备)。
  3. 输入任意文本(如 hello),点击“发送”。
  4. 通过条件:tvResult 显示QNX返回的响应文本(如 ECHO: hello)。若显示 ERROR: ...,检查IP/端口配置及QNX服务是否运行。

常见问题

  • 连接超时:确认QNX服务端已启动且防火墙未拦截端口;模拟器使用 10.0.2.2 访问宿主机,真机需填写QNX设备实际IP。
  • 主线程网络异常:本案例使用 AsyncTask 规避,实际工程建议改用 Thread + Handler 或协程。
  • 中文乱码:确保两端统一使用UTF-8编码(OutputStreamWriter 可指定字符集)。