Android的Service和Thread的区别
Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。
Android Service是组件,既不能说它是单独的进程也不能说它是单独的线程。
如果非要从通俗的语言层面来理解的话,姑且将其理解为对象。这个Service对象本身作为应用程序的一部分与它的调用者运行在相同的进程,当然如果指定了process则会运行到另外的进程。指定到其他进程的方法参加Service属性的"android:process"。
Android Service可以在后台运行,不需要给用户提供任何的界面。但是Service是默认运行在主线程的,不要以为可以直接把它放在后台作耗时操作,如果要做耗时操作还是需要在Service里另起线程的,否则你懂得,会阻塞主线程造成ANR。
Service是组件:默认运行在当前进程的主线程中的,如果需要执行耗时操作,记得在Service里创建新线程;
Service用来提高优先级:在后台场景下,Service的优先级是高于后台挂起的Activity的,也高于Activity所创建的线程。这样的话,在内存不足时,Service不会被优先杀死
import android.content.Intent;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;import xx.MyApplication;
import xx.MySQLiteOpenHelper;
import xx.entity.UploadTaskEntity;
import xx.sharedpreference.SharedPreferenceConstant;import java.lang.ref.WeakReference;public class UploadTaskService extends android.app.Service {private MyHandler myHandler;private java.util.concurrent.ScheduledExecutorService scheduledExecutorService;private int timesForSuccess;private int timesForFailure;private int timesForNothing;@Nullable@Overridepublic IBinder onBind(Intent intent) {android.util.Log.d("debug", "服务在绑定的时候");return new MyServiceBinder();}@Overridepublic void onCreate() {super.onCreate();android.util.Log.d("debug", "服务在创建的时候");WeakReference<UploadTaskService> myServiceWeakReference = new WeakReference<UploadTaskService>(this);myHandler = new MyHandler(myServiceWeakReference);scheduledExecutorService = new java.util.concurrent.ScheduledThreadPoolExecutor(3, java.util.concurrent.Executors.defaultThreadFactory());java.util.concurrent.ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(new NetworkRunnable(), 10, 30, java.util.concurrent.TimeUnit.SECONDS);boolean isDone = scheduledFuture.isDone();android.util.Log.d("debug", "调度未来是否完成->" + isDone);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();intent.setComponent(componentName);android.content.ComponentName componentNameResult = startForegroundService(intent);if (componentNameResult != null) {android.util.Log.d("debug", "开启前台服务返回的结果->" + componentNameResult.getShortClassName());}android.app.NotificationChannel notificationChannel = new android.app.NotificationChannel("persistent", "persistent", android.app.NotificationManager.IMPORTANCE_LOW);java.lang.Object objectNotificationManger = getSystemService(NOTIFICATION_SERVICE);if (objectNotificationManger instanceof android.app.NotificationManager) {android.app.NotificationManager notificationManager = (android.app.NotificationManager) objectNotificationManger;notificationManager.createNotificationChannel(notificationChannel);android.app.Notification notification = new android.support.v4.app.NotificationCompat.Builder(this, "persistent").setAutoCancel(true).setCategory(android.app.Notification.CATEGORY_SERVICE).setOngoing(true).setPriority(android.app.NotificationManager.IMPORTANCE_LOW).build();startForeground(10, notification);}}}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if (intent != null) {android.util.Log.d("debug", "服务在开始命令的时候(intent)->" + intent.getAction());}android.util.Log.d("debug", "服务在开始命令的时候(flags)->" + flags);android.util.Log.d("debug", "服务在开始命令的时候(startId)->" + startId);return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();android.util.Log.d("debug", "服务在销毁的时候");scheduledExecutorService.shutdown();}@Overridepublic boolean onUnbind(Intent intent) {android.util.Log.d("debug", "服务在解绑的时候");return super.onUnbind(intent);}@Overridepublic void onRebind(Intent intent) {super.onRebind(intent);android.util.Log.d("debug", "服务在重新绑定的时候");}@Overridepublic void onTaskRemoved(Intent rootIntent) {super.onTaskRemoved(rootIntent);android.util.Log.d("debug", "服务在任务移除的时候");}public void startNetwork() {android.util.Log.d("debug", "手动触发上传");Thread thread = new Thread(new NetworkRunnable());thread.setName("manualThread");thread.start();}public boolean getScheduledExecutorServiceIsShutDown() {return scheduledExecutorService.isShutdown();}public java.util.Properties getProperties() {java.util.Properties properties = new java.util.Properties();properties.put("timesForSuccess", timesForSuccess);properties.put("timesForFailure", timesForFailure);properties.put("timesForNothing", timesForNothing);return properties;}private void responseSuccessForNetwork(String result) {android.util.Log.d("debug", "异步任务响应成功->" + result);timesForSuccess ++;}private void responseFailureForNetwork(String result) {android.util.Log.d("debug", "异步任务响应失败->" + result);timesForFailure ++;}private void nothingResponse() {timesForNothing ++;}public class MyServiceBinder extends android.os.Binder {public UploadTaskService getMyService() {return UploadTaskService.this;}}protected static class MyHandler extends android.os.Handler {private final WeakReference<UploadTaskService> myServiceWeakReference;public MyHandler(WeakReference<UploadTaskService> myServiceWeakReference) {this.myServiceWeakReference = myServiceWeakReference;}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);UploadTaskService uploadTaskService = myServiceWeakReference.get();if (uploadTaskService != null) {String result = (String) msg.obj;if (msg.what == -1) {uploadTaskService.nothingResponse();} else if (msg.what == 0) {uploadTaskService.responseSuccessForNetwork(result);} else if (msg.what == 1) {uploadTaskService.responseFailureForNetwork(result);}}}}protected class NetworkRunnable implements Runnable {@Overridepublic void run() {android.app.Application application = getApplication();if (application == null) {return;}android.content.SharedPreferences sharedPreferencesMulti = getSharedPreferences(SharedPreferenceConstant.NAME, android.content.Context.MODE_MULTI_PROCESS);String authorization = sharedPreferencesMulti.getString(SharedPreferenceConstant.TOKEN, null);authorization = authorization == null ? "Bearer " : "Bearer " + authorization;java.util.List<UploadTaskEntity> uploadTaskEntityList = new java.util.ArrayList<UploadTaskEntity>();MyApplication myApplication = (MyApplication) application;MySQLiteOpenHelper mySQLiteOpenHelper = myApplication.getMySQLiteOpenHelper();android.database.sqlite.SQLiteDatabase sqLiteDatabaseForReadable = mySQLiteOpenHelper.getReadableDatabase();String[] selectionArgs = new String[1];selectionArgs[0] = "0";android.database.Cursor cursor = sqLiteDatabaseForReadable.rawQuery("SELECT * FROM upload_task WHERE upload_status = ?;", selectionArgs);while (cursor.moveToNext()) {int id = cursor.getInt(cursor.getColumnIndex("id"));android.util.Log.d("debug", "id->" + id);String url = cursor.getString(cursor.getColumnIndex("url"));String method = cursor.getString(cursor.getColumnIndex("method"));String body = cursor.getString(cursor.getColumnIndex("body"));int uploadStatus = cursor.getInt(cursor.getColumnIndex("upload_status"));String remark = cursor.getString(cursor.getColumnIndex("remark"));String createTimestamp = cursor.getString(cursor.getColumnIndex("create_timestamp"));UploadTaskEntity uploadTaskEntity = new UploadTaskEntity();uploadTaskEntity.setId(id);uploadTaskEntity.setUrl(url);uploadTaskEntity.setMethod(method);uploadTaskEntity.setBody(body);uploadTaskEntity.setUploadStatus(uploadStatus);uploadTaskEntity.setRemark(remark);uploadTaskEntity.setCreateTimestamp(createTimestamp);uploadTaskEntityList.add(uploadTaskEntity);}cursor.close();if (uploadTaskEntityList.size() > 0) {for (UploadTaskEntity uploadTaskEntity : uploadTaskEntityList) {android.database.sqlite.SQLiteDatabase sqLiteDatabaseForWritable = mySQLiteOpenHelper.getWritableDatabase();android.content.ContentValues contentValues = new android.content.ContentValues(1);contentValues.put("upload_status", 1);String[] whereArgs = new String[1];whereArgs[0] = String.valueOf(uploadTaskEntity.getId());int updateResult = sqLiteDatabaseForWritable.update("upload_task", contentValues, "id = ?", whereArgs);android.util.Log.d("debug", "打印更新状态为1返回的结果->" + updateResult);boolean isSuccess = false;String result;java.net.HttpURLConnection httpURLConnection = null;java.io.BufferedReader bufferedReader = null;java.io.OutputStreamWriter outputStreamWriter = null;try {java.net.URL url = new java.net.URL(uploadTaskEntity.getUrl());android.util.Log.d("debug", "url->" + url + "\r\nrequest body->" + uploadTaskEntity.getBody());java.net.URLConnection urlConnection = url.openConnection();httpURLConnection = (java.net.HttpURLConnection) urlConnection;httpURLConnection.setRequestMethod(uploadTaskEntity.getMethod());httpURLConnection.setConnectTimeout(1000 * 30);httpURLConnection.setReadTimeout(1000 * 30);httpURLConnection.setRequestProperty("Authorization", authorization);httpURLConnection.setRequestProperty("Content-Type", "application/json");if (uploadTaskEntity.getMethod().equals("POST")) {httpURLConnection.setUseCaches(false);httpURLConnection.setDoOutput(true);}httpURLConnection.setDoInput(true);if (uploadTaskEntity.getMethod().equals("POST")) {java.io.OutputStream outputStream = httpURLConnection.getOutputStream();outputStreamWriter = new java.io.OutputStreamWriter(outputStream, "UTF-8");outputStreamWriter.write(uploadTaskEntity.getBody());outputStreamWriter.flush();} else {httpURLConnection.connect();}int responseCode = httpURLConnection.getResponseCode();if (responseCode == 200) {java.io.InputStream inputStream = httpURLConnection.getInputStream();java.io.InputStreamReader inputStreamReader = new java.io.InputStreamReader(inputStream, "UTF-8");bufferedReader = new java.io.BufferedReader(inputStreamReader);StringBuilder stringBuilder = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line);}isSuccess = true;result = stringBuilder.toString();} else {result = String.valueOf(responseCode);}android.util.Log.d("debug", "url->" + url + "\r\nresponse body->" + result);} catch (java.io.IOException ioException) {ioException.printStackTrace();result = ioException.getMessage();} finally {if (bufferedReader != null) {try {bufferedReader.close();} catch (java.io.IOException ioException) {ioException.printStackTrace();}}if (outputStreamWriter != null) {try {outputStreamWriter.close();} catch (java.io.IOException ioException) {ioException.printStackTrace();}}if (httpURLConnection != null) {httpURLConnection.disconnect();}}Message message = myHandler.obtainMessage();message.what = isSuccess ? 0 : 1;message.obj = result;boolean sentResult = myHandler.sendMessage(message);android.util.Log.d("debug", "在线程发送消息到服务返回的结果->" + sentResult);if (isSuccess) {String[] whereArgs1 = new String[1];whereArgs1[0] = String.valueOf(uploadTaskEntity.getId());int deleteResult = sqLiteDatabaseForWritable.delete("upload_task", "id = ?", whereArgs1);android.util.Log.d("debug", "打印上传成功之后删除本地的返回的结果->" + deleteResult);} else {android.content.ContentValues contentValues1 = new android.content.ContentValues(2);contentValues1.put("upload_status", 0);contentValues1.put("remark", result);String[] whereArgs1 = new String[1];whereArgs1[0] = String.valueOf(uploadTaskEntity.getId());int updateResult1 = sqLiteDatabaseForWritable.update("upload_task", contentValues1, "id = ?", whereArgs1);android.util.Log.d("debug", "打印更新上传状态为0返回的结果->" + updateResult1);}}} else {android.util.Log.d("debug", "暂无可上传的任务");boolean sentResult = myHandler.sendEmptyMessage(-1);android.util.Log.d("debug", "发送空消息返回的结果->" + sentResult);}}}
}
ServiceConnection是Service和Activity通讯的组件
import android.content.ComponentName;
import android.os.IBinder;public class UploadTaskServiceConnection implements android.content.ServiceConnection {private UploadTaskService uploadTaskService = null;@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {android.util.Log.d("debug", "在服务连接的时候(name)->" + name.getShortClassName());if (service instanceof UploadTaskService.MyServiceBinder) {UploadTaskService.MyServiceBinder myServiceBinder = (UploadTaskService.MyServiceBinder) service;uploadTaskService = myServiceBinder.getMyService();}}@Overridepublic void onServiceDisconnected(ComponentName name) {android.util.Log.d("debug", "在服务断开连接的时候(name)->" + name.getShortClassName());}public UploadTaskService getMyService() {return uploadTaskService;}
}
Activity和Service之间通讯的示例
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;import xx.R;
import xx.adapter.UploadTaskAdapter;
import xx.pub.MyApplication;
import xx.pub.db.MySQLiteOpenHelper;
import xx.pub.entity.UploadTaskEntity;
import xx.service.UploadTaskService;
import xx.service.UploadTaskServiceConnection;public class UploadTaskServiceActivity extends android.support.v7.app.AppCompatActivity implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener, UploadTaskAdapter.OnItemChildClickListenerForCustom {private UploadTaskServiceConnection uploadTaskServiceConnection = null;private UploadTaskAdapter uploadTaskAdapter;private android.support.v4.widget.SwipeRefreshLayout swipeRefreshLayout;private android.widget.TextView textViewDisplayProperties;private android.widget.TextView textViewServiceIsRunning;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_upload_task_service);android.support.v7.widget.Toolbar toolbar = findViewById(R.id.activity_upload_task_service_toolbar);setSupportActionBar(toolbar);android.widget.Button buttonStartService = findViewById(R.id.activity_upload_task_service_button_start_service);android.widget.Button buttonStopService = findViewById(R.id.activity_upload_task_service_button_stop_service);android.widget.Button buttonBindService = findViewById(R.id.activity_upload_task_service_button_bind_service);android.widget.Button buttonUnbindService = findViewById(R.id.activity_upload_task_service_button_unbind_service);android.widget.Button buttonNetworkOnService = findViewById(R.id.activity_upload_task_service_button_network_on_service);android.widget.Button buttonGetScheduledStatus = findViewById(R.id.activity_upload_task_service_button_get_scheduled_status);android.widget.Button buttonGetProperties = findViewById(R.id.activity_upload_task_service_button_get_properties);android.widget.Button buttonGetServiceIsRunning = findViewById(R.id.activity_upload_task_service_button_get_service_is_running);textViewDisplayProperties = findViewById(R.id.activity_upload_task_service_text_display_properties);textViewServiceIsRunning = findViewById(R.id.activity_upload_task_service_text_view_service_is_running);buttonStartService.setOnClickListener(this);buttonStopService.setOnClickListener(this);buttonBindService.setOnClickListener(this);buttonUnbindService.setOnClickListener(this);buttonNetworkOnService.setOnClickListener(this);buttonGetScheduledStatus.setOnClickListener(this);buttonGetProperties.setOnClickListener(this);buttonGetServiceIsRunning.setOnClickListener(this);swipeRefreshLayout = findViewById(R.id.activity_upload_task_service_swipe_refresh_layout);swipeRefreshLayout.setOnRefreshListener(this);android.widget.ListView listView = findViewById(R.id.activity_upload_task_service_list_view);uploadTaskAdapter = new UploadTaskAdapter(this, readUploadTaskEntityListForAll());uploadTaskAdapter.setOnItemChildClickListenerForCustom(this);listView.setAdapter(uploadTaskAdapter);}private boolean isRunningForService() {boolean isRunning = false;Object activityServiceObject = getSystemService(ACTIVITY_SERVICE);if (activityServiceObject instanceof android.app.ActivityManager) {android.content.ComponentName componentNameOfMyService = new android.content.ComponentName(this, UploadTaskService.class);android.app.ActivityManager activityManager = (android.app.ActivityManager) activityServiceObject;java.util.List<android.app.ActivityManager.RunningServiceInfo> runningServiceInfoList = activityManager.getRunningServices(Integer.MAX_VALUE);if (runningServiceInfoList != null && runningServiceInfoList.size() > 0) {for (android.app.ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfoList) {android.content.ComponentName componentName = runningServiceInfo.service;String className = componentName.getClassName();android.util.Log.d("debug", "正在运行中的服务->" + className);int compareResult = componentName.compareTo(componentNameOfMyService);android.util.Log.d("debug", "打印比较结果->" + compareResult);if (compareResult == 0) {isRunning = true;break;}}}}return isRunning;}private void bindService() {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();android.content.Intent intentResult = intent.setComponent(componentName);uploadTaskServiceConnection = new UploadTaskServiceConnection();boolean bindServiceResult = bindService(intent, uploadTaskServiceConnection, 0);String text = "绑定服务的结果:" + bindServiceResult;android.util.Log.d("debug", text);}private void startService() {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();android.content.Intent intentResult = intent.setComponent(componentName);android.content.ComponentName componentNameResult = startService(intent);if (componentNameResult != null) {String shortClassName = componentNameResult.getShortClassName();android.util.Log.d("debug", "开始的服务的短类名->" + shortClassName);}}@Overrideprotected void onResume() {super.onResume();if (isRunningForService()) {if (uploadTaskServiceConnection != null) {unbindService(uploadTaskServiceConnection);uploadTaskServiceConnection = null;}} else {startService();}bindService();}private java.util.List<UploadTaskEntity> readUploadTaskEntityListForAll() {MyApplication myApplication = (MyApplication) getApplication();MySQLiteOpenHelper mySQLiteOpenHelper = myApplication.getMySQLiteOpenHelper();android.database.sqlite.SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getReadableDatabase();android.database.Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM upload_task;", null);java.util.List<UploadTaskEntity> uploadTaskEntityList = new java.util.ArrayList<UploadTaskEntity>();while (cursor.moveToNext()) {int id = cursor.getInt(cursor.getColumnIndex("id"));String url = cursor.getString(cursor.getColumnIndex("url"));String method = cursor.getString(cursor.getColumnIndex("method"));String body = cursor.getString(cursor.getColumnIndex("body"));int uploadStatus = cursor.getInt(cursor.getColumnIndex("upload_status"));String remark = cursor.getString(cursor.getColumnIndex("remark"));String createTimestamp = cursor.getString(cursor.getColumnIndex("create_timestamp"));UploadTaskEntity uploadTaskEntity = new UploadTaskEntity();uploadTaskEntity.setId(id);uploadTaskEntity.setUrl(url);uploadTaskEntity.setMethod(method);uploadTaskEntity.setBody(body);uploadTaskEntity.setUploadStatus(uploadStatus);uploadTaskEntity.setRemark(remark);uploadTaskEntity.setCreateTimestamp(createTimestamp);uploadTaskEntityList.add(uploadTaskEntity);}cursor.close();return uploadTaskEntityList;}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {android.view.MenuInflater menuInflater = getMenuInflater();menuInflater.inflate(R.menu.menu_upload_task_service, menu);return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {if (item.getItemId() == android.R.id.home) {finish();} else if (item.getItemId() == R.id.menu_test_service_create_upload_task) {View view = android.view.LayoutInflater.from(this).inflate(R.layout.dialog_create_upload_task, null);final android.widget.EditText editTextUrl = view.findViewById(R.id.dialog_create_upload_task_edit_text_url);final android.widget.EditText editTextMethod = view.findViewById(R.id.dialog_create_upload_task_edit_text_method);final android.widget.EditText editTextBody = view.findViewById(R.id.dialog_create_upload_task_edit_text_body);new AlertDialog.Builder(this).setView(view).setNegativeButton("取消", null).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String url = editTextUrl.getText().toString();String method = editTextMethod.getText().toString();String body = editTextBody.getText().toString();android.app.Application application = getApplication();MyApplication myApplication = (MyApplication) application;MySQLiteOpenHelper mySQLiteOpenHelper = myApplication.getMySQLiteOpenHelper();android.database.sqlite.SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();android.content.ContentValues contentValues = new android.content.ContentValues(4);contentValues.put("url", url);contentValues.put("method", method);contentValues.put("body", body);contentValues.put("upload_status", 0);long insertResult = sqLiteDatabase.insert("upload_task", null, contentValues);android.util.Log.d("debug", "插入结果->" + insertResult);Toast.makeText(UploadTaskServiceActivity.this, "创建上传任务结果:" + insertResult, Toast.LENGTH_SHORT).show();uploadTaskAdapter.setNewData(readUploadTaskEntityListForAll());}}).create().show();}return super.onOptionsItemSelected(item);}@Overrideprotected void onDestroy() {super.onDestroy();if (uploadTaskServiceConnection != null) {unbindService(uploadTaskServiceConnection);}}@Overridepublic void onClick(View v) {if (v.getId() == R.id.activity_upload_task_service_button_start_service) {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();android.content.Intent intentResult = intent.setComponent(componentName);android.content.ComponentName componentNameResult = startService(intent);if (componentNameResult != null) {String shortClassName = componentNameResult.getShortClassName();android.util.Log.d("debug", "开始的服务的短类名->" + shortClassName);String className = componentNameResult.getClassName();android.util.Log.d("debug", "开始的服务的类名->" + className);String text = "开始服务的类名:" + shortClassName;Toast.makeText(this, text, Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_stop_service) {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();android.content.Intent intentResult = intent.setComponent(componentName);boolean stopServiceResult = stopService(intent);String text = "停止服务的结果:" + stopServiceResult;Toast.makeText(this, text, Toast.LENGTH_SHORT).show();} else if (v.getId() == R.id.activity_upload_task_service_button_bind_service) {if (uploadTaskServiceConnection != null) {Toast.makeText(this, "服务已经绑定,无需重复绑定", Toast.LENGTH_SHORT).show();} else {android.content.ComponentName componentName = new android.content.ComponentName(this, UploadTaskService.class);android.content.Intent intent = new android.content.Intent();android.content.Intent intentResult = intent.setComponent(componentName);uploadTaskServiceConnection = new UploadTaskServiceConnection();boolean bindServiceResult = bindService(intent, uploadTaskServiceConnection, 0);String text = "绑定服务的结果:" + bindServiceResult;Toast.makeText(this, text, Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_unbind_service) {if (uploadTaskServiceConnection != null) {unbindService(uploadTaskServiceConnection);uploadTaskServiceConnection = null;Toast.makeText(this, "解除绑定完成", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "无绑定服务,不用解绑", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_network_on_service) {if (uploadTaskServiceConnection != null) {UploadTaskService uploadTaskService = uploadTaskServiceConnection.getMyService();if (uploadTaskService != null) {uploadTaskService.startNetwork();Toast.makeText(this, "后台服务已经在上传...", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "服务是空的,可能是绑定失败", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(this, "还没有绑定服务,请先绑定服务", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_get_scheduled_status) {if (uploadTaskServiceConnection != null) {UploadTaskService uploadTaskService = uploadTaskServiceConnection.getMyService();if (uploadTaskService != null) {boolean isShutDown = uploadTaskService.getScheduledExecutorServiceIsShutDown();Toast.makeText(this, "调度服务是否关闭:" + isShutDown, Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "服务是空的,可能是绑定失败", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(this, "还没有绑定服务,请先绑定服务", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_get_properties) {if (uploadTaskServiceConnection != null) {UploadTaskService uploadTaskService = uploadTaskServiceConnection.getMyService();if (uploadTaskService != null) {java.util.Properties properties = uploadTaskService.getProperties();Integer timesForSuccess = (Integer) properties.get("timesForSuccess");Integer timesForFailure = (Integer) properties.get("timesForFailure");Integer timesForNothing = (Integer) properties.get("timesForNothing");String text = "success:" + timesForSuccess + ";failure:" + timesForFailure + ";nothing:" + timesForNothing;textViewDisplayProperties.setText(text);} else {Toast.makeText(this, "服务是空的,可能是绑定失败", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(this, "还没有绑定服务,请先绑定服务", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.activity_upload_task_service_button_get_service_is_running) {boolean isRunning = false;Object activityServiceObject = getSystemService(ACTIVITY_SERVICE);if (activityServiceObject instanceof android.app.ActivityManager) {android.content.ComponentName componentNameOfMyService = new android.content.ComponentName(this, UploadTaskService.class);android.app.ActivityManager activityManager = (android.app.ActivityManager) activityServiceObject;java.util.List<android.app.ActivityManager.RunningServiceInfo> runningServiceInfoList = activityManager.getRunningServices(Integer.MAX_VALUE);if (runningServiceInfoList != null && runningServiceInfoList.size() > 0) {for (android.app.ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfoList) {android.content.ComponentName componentName = runningServiceInfo.service;String className = componentName.getClassName();android.util.Log.d("debug", "正在运行中的服务->" + className);int compareResult = componentName.compareTo(componentNameOfMyService);android.util.Log.d("debug", "打印比较结果->" + compareResult);if (compareResult == 0) {isRunning = true;break;}}}}String text = "后台上传服务是否在运行:" + isRunning;textViewServiceIsRunning.setText(text);}}@Overridepublic void onRefresh() {uploadTaskAdapter.setNewData(readUploadTaskEntityListForAll());swipeRefreshLayout.setRefreshing(false);}@Overridepublic void onItemChildClickForCustom(Integer position, int viewId) {Object object = uploadTaskAdapter.getItem(position);if (object instanceof UploadTaskEntity) {final UploadTaskEntity uploadTaskEntity = (UploadTaskEntity) object;if (viewId == R.id.item_upload_task_text_view_delete) {String message = "你确定要删除任务ID为" + uploadTaskEntity.getId() + "的上传任务吗?";new AlertDialog.Builder(this).setMessage(message).setNegativeButton("取消", null).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {int deleteResult = deleteUploadTaskEntityById(uploadTaskEntity.getId());Toast.makeText(UploadTaskServiceActivity.this, "删除数量:" + deleteResult, Toast.LENGTH_SHORT).show();uploadTaskAdapter.setNewData(readUploadTaskEntityListForAll());}}).create().show();} else if (viewId == R.id.item_upload_task_text_view_copy) {Object objectForClipboardService = getSystemService(CLIPBOARD_SERVICE);if (objectForClipboardService instanceof android.content.ClipboardManager) {android.content.ClipboardManager clipboardManager = (android.content.ClipboardManager) objectForClipboardService;clipboardManager.setText(uploadTaskEntity.toString());Toast.makeText(this, "复制成功", Toast.LENGTH_SHORT).show();}}}}private int deleteUploadTaskEntityById(int id) {MyApplication myApplication = (MyApplication) getApplication();MySQLiteOpenHelper mySQLiteOpenHelper = myApplication.getMySQLiteOpenHelper();android.database.sqlite.SQLiteDatabase sqLiteDatabase = mySQLiteOpenHelper.getWritableDatabase();String[] whereArgs = new String[1];whereArgs[0] = String.valueOf(id);return sqLiteDatabase.delete("upload_task", "id = ?", whereArgs);}
}
相关文章:
Android的Service和Thread的区别
Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。 Android Service是组件,既不能说它是单独的进程也不能说它是单独的线程。 如果非要从通俗的语言层面来理解的话,姑且将其理解为对象。这个Service对象本身作为应用程序的一部分与它的…...

经纬恒润亮相第四届焉知汽车年会,功能安全赋能域控
8月初,第四届焉知汽车年会在上海举行。此次年会围绕当下智能电动汽车的热点和焦点,聚焦于智能汽车场景应用、车载通信、激光雷达、智能座舱、功能安全、电驱动系统等多个领域,汇聚了来自OEM、科技公司、零部件供应商、测试认证机构、政府院校…...
掌握JavaScript单元测试:最佳实践与技术指南
单元测试是软件开发过程中的关键环节,它帮助开发者确保代码的每个独立部分按预期工作。在JavaScript开发中,进行单元测试不仅可以提高代码质量,还可以加快开发速度,因为它们为代码更改提供了安全网。本文将详细介绍如何使用JavaSc…...

spring boot 古茶树管理系统---附源码19810
目 录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2古茶树管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2经济可行性分析 2.1.3操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 …...
00067期 matlab中的asv文件
今天在编写代码的过程中,发现自动生成.m文件的同名文件.asv,特此发出疑问?下面是解答: 有时在存放m文件的文件夹中会出现*.asv asv 就是auto save的意思,*.asv文件的内容和相应的*.m文件内容一样,用记…...

JMeter高效管理测试数据-参数化
文章目录 1.什么是参数化2.定义变量3.CSV数据文件设置 1.什么是参数化 在JMeter中,参数化是一种常用的技术,用于使测试场景更加灵活和动态。通过参数化,你可以让JMeter在每次请求中使用不同的值,这在模拟真实用户行为或测试不同输…...
python学习之writelines
在Python中,writelines() 是一个方法,它属于文件对象,用于将字符串列表写入到文件中。这个方法接受一个序列(如列表或元组)作为参数,序列中的每个元素都是要写入的一行文本。 ### 函数定义: p…...

STM32学习笔记13-FLASH闪存
FLASH简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程读写FLASH的用途: 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 通过在…...

UIButton的UIEdgeInsetsMake属性(setTitleEdgeInsets,setImageEdgeInsets)
一.UIEdgeInsetsMake的四个属性 UIEdgeInsetsMake 有四个属性,依次是 Top,left,bottom,right [Btn setTitleEdgeInsets:UIEdgeInsetsMake( top, left, bottom, right)]; 四个属性的默认值为0,拿其中一个left属性来聊, 你可以理解为文字距离Btn左边界的“位移”是0, 如果…...

子网掩码是什么?
子网掩码(Subnet Mask)是用于划分网络的一个32位的二进制数,用于指示IP地址中哪些位用于网络标识,哪些位用于主机标识。 在IPv4网络中,IP地址由32位二进制数组成,通常表示为四个十进制数,每个数…...
SQLALchemy 数据的 CRUD 操作
SQLALchemy 数据的 CRUD 操作 导入必要的模块创建数据库引擎创建会话CRUD 操作创建(Create)读取(Read)更新(Update)删除(Delete)过滤条件使用 `filter` 方法使用 `filter_by` 方法总结聚合函数使用ORM接口使用SQL表达式语言注意关闭会话注意事项SQLAlchemy 是一个流行的…...

reactFiberLane
Lane (车道模型) 英文单词lane翻译成中文表示"车道, 航道"的意思, 所以很多文章都将Lanes模型称为车道模型 Lane模型的源码在ReactFiberLane.js, 源码中大量使用了位运算(有关位运算的讲解, 首先引入作者对Lane的解释(相应的 pr), 这里简单概括如下: Lane类型被定义…...

Hackademic.RTB1靶场实战【超详细】
靶机下载链接:https://download.vulnhub.com/hackademic/Hackademic.RTB1.zip 一、主机探测和端口扫描 nmap 192.168.121.0/24 ip:192.168.121.196 端口:22、80 二、访问80端口 发现target可点击 点击后跳转,页面提示目标是读取到 key.txt 文件 fin…...

让3岁小孩都能理解LeetCode每日一题_3148.矩阵中的最大得分
解释说明: 上面的内容的意思是为了有只移动一次的情况,而后面的grid(i,j)-grid(i,k)由于j严格大于k,所以至少移动了一次,前面可以保持不移动,不移动就是选择0。 class Solution {public int maxScore(List<List&l…...

8.15日学习打卡---Spring Cloud Alibaba(三)
8.15日学习打卡 目录: 8.15日学习打卡为什么需要服务网关Higress是什么安装DockerCompose部署Higress创建网关微服务模块Higress路由配置Higress策略配置-跨域配置Higress解决如何允许跨域Higress策略配置之什么是HTTP认证Higress策略配置-Basic 认证什么是JWT认证J…...

2024下半年EI学术会议一览表
2024下半年将举办多个重要的EI学术会议,涵盖了从机器视觉、图像处理与影像技术到感知技术、绿色通信、计算机、大数据与人工智能等多个领域。 2024下半年EI学术会议一览表 第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)将于2024…...

【海奇HC-RTOS平台E100-问题点】
海奇HC-RTOS平台E100-问题点 ■ btn 没有添加到group中 ,怎么实现的事件的■ 屏幕是1280*720, UI是1024*600,是否修改UI■ hc15xx-db-e100-v10-hcdemo.dtb 找不到■ 触摸屏驱动 能否给个实例■ 按键驱动■ __initcall(projector_auto_start)■ source insigt4.0 #if…...

性能测试之Mysql数据库调优
一、前言 性能调优前提:无监控不调优,对于mysql性能的监控前几天有文章提到过,有兴趣的朋友可以去看一下 二、Mysql性能指标及问题分析和定位 1、我们在监控图表中关注的性能指标大概有这么几个:CPU、内存、连接数、io读写时间…...
使用 RestHighLevelClient 进行 Elasticsearch 高亮查询及解析
在搜索引擎中,高亮显示查询关键字是一个提升用户体验的功能,它可以帮助用户更快地定位到相关信息。Elasticsearch 支持在搜索结果中对匹配的文本进行高亮显示。本文将介绍如何在 Java 应用程序中使用 Elasticsearch 的 RestHighLevelClient 执行高亮查询…...

Java基础入门15:算法、正则表达式、异常
算法(选择排序、冒泡排序、二分查找) 选择排序 每轮选择当前位置,开始找出后面的较小值与该位置交换。 选择排序的关键: 确定总共需要选择几轮:数组的长度-1。 控制每轮从以前位置为基准,与后面元素选择…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...