feat: 改为MVVM
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
android:theme="@style/Theme.MaterialComponents.DayNight">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".activity.main.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.ttstd.controlled;
|
||||
package com.ttstd.controlled.activity.main;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ComponentName;
|
||||
@@ -8,39 +8,29 @@ import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.projection.MediaProjectionManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.ttstd.controlled.R;
|
||||
import com.ttstd.controlled.base.BaseMvvmActivity;
|
||||
import com.ttstd.controlled.databinding.ActivityMainBinding;
|
||||
import com.ttstd.controlled.service.ScreenCaptureService;
|
||||
import com.ttstd.controlled.webrtc.WebRtcClient;
|
||||
|
||||
import org.webrtc.RendererCommon;
|
||||
import org.webrtc.SurfaceViewRenderer;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBinding> {
|
||||
|
||||
private static final String TAG = "ControlledMain";
|
||||
private static final int REQUEST_MEDIA_PROJECTION = 1001;
|
||||
private static final int REQUEST_NOTIFICATION_PERMISSION = 1002;
|
||||
|
||||
private EditText etServerUrl;
|
||||
private EditText etDeviceId;
|
||||
private Button btnStart;
|
||||
private Button btnStop;
|
||||
private TextView tvStatus;
|
||||
private SurfaceViewRenderer localView;
|
||||
|
||||
private boolean isServiceRunning = false;
|
||||
private ScreenCaptureService screenCaptureService;
|
||||
private boolean isBound = false;
|
||||
@@ -63,28 +53,28 @@ public class MainActivity extends AppCompatActivity {
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
etServerUrl = findViewById(R.id.et_server_url);
|
||||
etDeviceId = findViewById(R.id.et_device_id);
|
||||
btnStart = findViewById(R.id.btn_start);
|
||||
btnStop = findViewById(R.id.btn_stop);
|
||||
tvStatus = findViewById(R.id.tv_status);
|
||||
localView = findViewById(R.id.local_view);
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_main;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
// 默认服务器地址
|
||||
etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
||||
binding.etServerUrl.setText("ws://175.178.213.60:8088/ws/signal");
|
||||
// 生成设备ID
|
||||
// etDeviceId.setText("controlled_" + UUID.randomUUID().toString().substring(0, 8));
|
||||
// binding.etDeviceId.setText("controlled_" + UUID.randomUUID().toString().substring(0, 8));
|
||||
|
||||
btnStart.setOnClickListener(v -> startScreenSharing());
|
||||
btnStop.setOnClickListener(v -> stopScreenSharing());
|
||||
binding.btnStart.setOnClickListener(v -> startScreenSharing());
|
||||
binding.btnStop.setOnClickListener(v -> stopScreenSharing());
|
||||
|
||||
updateUI(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
// Initialization logic if any
|
||||
}
|
||||
|
||||
private void startScreenSharing() {
|
||||
// 检查通知权限 (Android 13+)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
@@ -112,8 +102,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
Intent serviceIntent = new Intent(this, ScreenCaptureService.class);
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_RESULT_CODE, resultCode);
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_RESULT_DATA, data);
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_SERVER_URL, etServerUrl.getText().toString());
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_DEVICE_ID, etDeviceId.getText().toString());
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_SERVER_URL, binding.etServerUrl.getText().toString());
|
||||
serviceIntent.putExtra(ScreenCaptureService.EXTRA_DEVICE_ID, binding.etDeviceId.getText().toString());
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(serviceIntent);
|
||||
@@ -150,8 +140,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
Intent serviceIntent = new Intent(this, ScreenCaptureService.class);
|
||||
stopService(serviceIntent);
|
||||
if (localView != null) {
|
||||
localView.release();
|
||||
if (binding.localView != null) {
|
||||
binding.localView.release();
|
||||
isLocalViewInitialized = false;
|
||||
}
|
||||
updateUI(false);
|
||||
@@ -163,17 +153,17 @@ public class MainActivity extends AppCompatActivity {
|
||||
WebRtcClient webRtcClient = screenCaptureService.getWebRtcClient();
|
||||
if (webRtcClient != null && webRtcClient.getEglContext() != null) {
|
||||
try {
|
||||
localView.init(webRtcClient.getEglContext(), null);
|
||||
localView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
|
||||
localView.setMirror(false);
|
||||
webRtcClient.setLocalSink(localView);
|
||||
binding.localView.init(webRtcClient.getEglContext(), null);
|
||||
binding.localView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
|
||||
binding.localView.setMirror(false);
|
||||
webRtcClient.setLocalSink(binding.localView);
|
||||
isLocalViewInitialized = true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error initializing local view", e);
|
||||
}
|
||||
} else {
|
||||
// 如果 webRtcClient 还没准备好,稍后重试
|
||||
localView.postDelayed(this::setupLocalPreview, 500);
|
||||
binding.localView.postDelayed(this::setupLocalPreview, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,18 +175,18 @@ public class MainActivity extends AppCompatActivity {
|
||||
unbindService(serviceConnection);
|
||||
isBound = false;
|
||||
}
|
||||
if (localView != null) {
|
||||
localView.release();
|
||||
if (binding != null && binding.localView != null) {
|
||||
binding.localView.release();
|
||||
isLocalViewInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUI(boolean running) {
|
||||
isServiceRunning = running;
|
||||
btnStart.setEnabled(!running);
|
||||
btnStop.setEnabled(running);
|
||||
etServerUrl.setEnabled(!running);
|
||||
etDeviceId.setEnabled(!running);
|
||||
tvStatus.setText(running ? "状态: 运行中" : "状态: 已停止");
|
||||
binding.btnStart.setEnabled(!running);
|
||||
binding.btnStop.setEnabled(running);
|
||||
binding.etServerUrl.setEnabled(!running);
|
||||
binding.etDeviceId.setEnabled(!running);
|
||||
binding.tvStatus.setText(running ? "状态: 运行中" : "状态: 已停止");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.ttstd.controlled.activity.main;
|
||||
|
||||
import com.ttstd.controlled.base.BaseViewModel;
|
||||
|
||||
public class MainViewModel extends BaseViewModel {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ttstd.controlled.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
public abstract class BaseMvvmActivity<VM extends BaseViewModel, DB extends ViewDataBinding> extends AppCompatActivity {
|
||||
|
||||
protected VM viewModel;
|
||||
protected DB binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = DataBindingUtil.setContentView(this, getLayoutId());
|
||||
binding.setLifecycleOwner(this);
|
||||
|
||||
initViewModel();
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected abstract int getLayoutId();
|
||||
|
||||
protected abstract void initView();
|
||||
|
||||
protected abstract void initData();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void initViewModel() {
|
||||
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
|
||||
if (type != null) {
|
||||
Class<VM> viewModelClass = (Class<VM>) type.getActualTypeArguments()[0];
|
||||
viewModel = new ViewModelProvider(this).get(viewModelClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.ttstd.controlled.base;
|
||||
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
public class BaseViewModel extends ViewModel {
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import android.view.WindowManager;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.ttstd.controlled.MainActivity;
|
||||
import com.ttstd.controlled.activity.main.MainActivity;
|
||||
import com.ttstd.controlled.input.InputCommandHandler;
|
||||
import com.ttstd.controlled.signaling.SignalMessage;
|
||||
import com.ttstd.controlled.signaling.WebSocketClient;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".activity.main.MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
@@ -72,4 +77,5 @@
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user