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。 控制每轮从以前位置为基准,与后面元素选择…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

代理服务器-LVS的3种模式与调度算法
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:…...