通知与服务——服务Service——服务的绑定与解绑&延迟绑定服务与解绑服务
===============================================================================================
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn_start_bind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="启动并绑定服务" android:textColor="@color/black" android:textSize="17sp" /> <Button android:id="@+id/btn_unbind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="解绑并停止服务" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <TextView android:id="@+id/tv_immediate" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
代码:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.TextView; public class MainActivity8 extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "BindImmediateActivity"; private static TextView tv_immediate; // 声明一个文本视图对象 private Intent mIntent; // 声明一个意图对象 private static String mDesc; // 日志描述 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main8); tv_immediate = findViewById(R.id.tv_immediate); findViewById(R.id.btn_start_bind).setOnClickListener(this); findViewById(R.id.btn_unbind).setOnClickListener(this); mDesc = ""; // 创建一个通往立即绑定服务的意图 mIntent = new Intent(this, com.example.myapplication.BindImmediateService.class); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_start_bind) // 点击了绑定服务按钮 { // 绑定服务。如果服务未启动,则系统先启动该服务再进行绑定 boolean bindFlag = bindService(mIntent, mFirstConn, Context.BIND_AUTO_CREATE); Log.d(TAG, "bindFlag=" + bindFlag); } else if (v.getId() == R.id.btn_unbind) // 点击了解绑服务按钮 { if (mBindService != null) { // 解绑服务。如果先前服务立即绑定,则此时解绑之后自动停止服务 unbindService(mFirstConn); mBindService = null; } } } public static void showText(String desc) { if (tv_immediate != null) { mDesc = String.format("%s%s %s\n", mDesc, DateUtil.getNowDateTime("HH:mm:ss"), desc); tv_immediate.setText(mDesc); } } private com.example.myapplication.BindImmediateService mBindService; // 声明一个服务对象 private ServiceConnection mFirstConn = new ServiceConnection() { // 获取服务对象时的操作 public void onServiceConnected(ComponentName name, IBinder service) { // 如果服务运行于另外一个进程,则不能直接强制转换类型,否则会报错 mBindService = ((com.example.myapplication.BindImmediateService.LocalBinder) service).getService(); Log.d(TAG, "onServiceConnected"); } // 无法获取到服务对象时的操作 public void onServiceDisconnected(ComponentName name) { mBindService = null; Log.d(TAG, "onServiceDisconnected"); } }; }
BindImmediateService
package com.example.myapplication; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class BindImmediateService extends Service { private static final String TAG = "BindImmediateService"; private final IBinder mBinder = new LocalBinder(); // 创建一个粘合剂对象 // 定义一个当前服务的粘合剂,用于将该服务黏到活动页面的进程中 public class LocalBinder extends Binder { public BindImmediateService getService() { return BindImmediateService.this; } } private void refresh(String text) { Log.d(TAG, text); MainActivity8.showText(text); } @Override public void onCreate() { // 创建服务 super.onCreate(); refresh("onCreate"); } @Override public void onDestroy() { // 销毁服务 super.onDestroy(); refresh("onDestroy"); } @Override public IBinder onBind(Intent intent) { // 绑定服务。返回该服务的粘合剂对象 Log.d(TAG, "绑定服务开始旅程!"); refresh("onBind"); return mBinder; } @Override public void onRebind(Intent intent) { // 重新绑定服务 super.onRebind(intent); refresh("onRebind"); } @Override public boolean onUnbind(Intent intent) { // 解绑服务 Log.d(TAG, "绑定服务结束旅程!"); refresh("onUnbind"); return true; // 返回false表示只能绑定一次,返回true表示允许多次绑定 } }
DateUtil
package com.example.myapplication; import android.annotation.SuppressLint; import android.text.TextUtils; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @SuppressLint("SimpleDateFormat") public class DateUtil { // 获取当前的日期时间 public static String getNowDateTime(String formatStr) { String format = formatStr; if (TextUtils.isEmpty(format)) { format = "yyyyMMddHHmmss"; } SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(new Date()); } // 获取当前的时间 public static String getNowTime() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } // 获取当前的时间(精确到毫秒) public static String getNowTimeDetail() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(new Date()); } public static String getNowDate() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); return sdf.format(new Date()); } public static String getDate(Calendar calendar) { Date date = calendar.getTime(); // 创建一个日期格式化的工具 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 将当前日期时间按照指定格式输出格式化后的日期时间字符串 return sdf.format(date); } public static String getMonth(Calendar calendar) { Date date = calendar.getTime(); // 创建一个日期格式化的工具 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); // 将当前日期时间按照指定格式输出格式化后的日期时间字符串 return sdf.format(date); } public static Date formatString(String strTime) { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { date = sdf.parse(strTime); } catch (Exception e) { e.printStackTrace(); } return date; } }
===================================================================================================
===================================================================================================
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn_start" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="启动服务" android:textColor="@color/black" android:textSize="15sp" /> <Button android:id="@+id/btn_bind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="绑定服务" android:textColor="@color/black" android:textSize="15sp" /> <Button android:id="@+id/btn_unbind" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="解绑服务" android:textColor="@color/black" android:textSize="15sp" /> <Button android:id="@+id/btn_stop" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="停止服务" android:textColor="@color/black" android:textSize="15sp" /> </LinearLayout> <TextView android:id="@+id/tv_delay" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="5dp" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
代码:
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.TextView; public class MainActivity9 extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "BindDelayActivity"; private static TextView tv_delay; private Intent mIntent; // 声明一个意图对象 private static String mDesc; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main9); tv_delay = findViewById(R.id.tv_delay); findViewById(R.id.btn_start).setOnClickListener(this); findViewById(R.id.btn_bind).setOnClickListener(this); findViewById(R.id.btn_unbind).setOnClickListener(this); findViewById(R.id.btn_stop).setOnClickListener(this); mDesc = ""; // 创建一个通往延迟绑定服务的意图 mIntent = new Intent(this, BindDelayService.class); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_start) // 点击了开始服务按钮 { startService(mIntent); // 启动服务 } else if (v.getId() == R.id.btn_bind) // 点击了绑定服务按钮 { boolean bindFlag = bindService(mIntent, mFirstConn, Context.BIND_AUTO_CREATE); // 绑定服务 Log.d(TAG, "bindFlag=" + bindFlag); } else if (v.getId() == R.id.btn_unbind) // 点击了解绑服务按钮 { if (mBindService != null) { unbindService(mFirstConn); // 解绑服务 mBindService = null; } } else if (v.getId() == R.id.btn_stop) // 点击了停止服务按钮 { stopService(mIntent); // 停止服务 } } public static void showText(String desc) { if (tv_delay != null) { mDesc = String.format("%s%s %s\n", mDesc, DateUtil.getNowDateTime("HH:mm:ss"), desc); tv_delay.setText(mDesc); } } private BindDelayService mBindService; // 声明一个服务对象 private ServiceConnection mFirstConn = new ServiceConnection() { // 获取服务对象时的操作 public void onServiceConnected(ComponentName name, IBinder service) { // 如果服务运行于另外一个进程,则不能直接强制转换类型,否则会报错 mBindService = ((BindDelayService.LocalBinder) service).getService(); Log.d(TAG, "onServiceConnected"); } // 无法获取到服务对象时的操作 public void onServiceDisconnected(ComponentName name) { mBindService = null; Log.d(TAG, "onServiceDisconnected"); } }; }
BindDelayService
package com.example.myapplication; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class BindDelayService extends Service { private static final String TAG = "BindDelayService"; private final IBinder mBinder = new LocalBinder(); // 创建一个粘合剂对象 // 定义一个当前服务的粘合剂,用于将该服务黏到活动页面的进程中 public class LocalBinder extends Binder { public BindDelayService getService() { return BindDelayService.this; } } private void refresh(String text) { Log.d(TAG, text); MainActivity9.showText(text); } @Override public void onCreate() // 创建服务 { super.onCreate(); refresh("onCreate"); } @Override public void onDestroy() // 销毁服务 { super.onDestroy(); refresh("onDestroy"); } @Override public IBinder onBind(Intent intent) // 绑定服务。返回该服务的粘合剂对象 { Log.d(TAG, "绑定服务开始旅程!"); refresh("onBind"); return mBinder; } @Override public void onRebind(Intent intent) // 重新绑定服务 { super.onRebind(intent); refresh("onRebind"); } @Override public boolean onUnbind(Intent intent) // 解绑服务 { Log.d(TAG, "绑定服务结束旅程!"); refresh("onUnbind"); return true; // 返回false表示只能绑定一次,返回true表示允许多次绑定 } }
DateUtil
package com.example.myapplication; import android.annotation.SuppressLint; import android.text.TextUtils; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @SuppressLint("SimpleDateFormat") public class DateUtil { // 获取当前的日期时间 public static String getNowDateTime(String formatStr) { String format = formatStr; if (TextUtils.isEmpty(format)) { format = "yyyyMMddHHmmss"; } SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(new Date()); } // 获取当前的时间 public static String getNowTime() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } // 获取当前的时间(精确到毫秒) public static String getNowTimeDetail() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); return sdf.format(new Date()); } public static String getNowDate() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); return sdf.format(new Date()); } public static String getDate(Calendar calendar) { Date date = calendar.getTime(); // 创建一个日期格式化的工具 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 将当前日期时间按照指定格式输出格式化后的日期时间字符串 return sdf.format(date); } public static String getMonth(Calendar calendar) { Date date = calendar.getTime(); // 创建一个日期格式化的工具 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); // 将当前日期时间按照指定格式输出格式化后的日期时间字符串 return sdf.format(date); } public static Date formatString(String strTime) { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { date = sdf.parse(strTime); } catch (Exception e) { e.printStackTrace(); } return date; } }
=========================================================================================