通知与服务——服务Service——服务的启动和停止
服务是在后台默默运行着的Android组件,它与生命周期有关的方法说明如下:
onCreate:创建服务。
onStart:开始服务,Android 2.0以下版本使用,现已废弃。
onStartCommand:开始服务,Android 2.0及以上版本使用。
onDestroy:销毁服务。
onBind:绑定服务。
onUnbind:解除绑定。返回值为true表示允许再次绑定,之后再绑定服务时,不会调用onBind方法而是调用onRebind方法;返回值为false表示只能绑定一次,不能再次绑定。
onRebind:重新绑定。只有上次的onUnbind方法返回true时,再次绑定服务才会调用onRebind方法。
===================================================================
布局:
<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="17sp" /> <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="17sp" /> </LinearLayout> <TextView android:id="@+id/tv_normal" 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.annotation.SuppressLint; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; @SuppressLint("StaticFieldLeak") public class MainActivity7 extends AppCompatActivity implements View.OnClickListener { private static TextView tv_normal; private Intent mIntent; // 声明一个意图对象 private static String mDesc; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main7); tv_normal = findViewById(R.id.tv_normal); findViewById(R.id.btn_start).setOnClickListener(this); findViewById(R.id.btn_stop).setOnClickListener(this); mDesc = ""; // 创建一个通往普通服务的意图 mIntent = new Intent(this, NormalService.class); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_start)// 点击了启动服务按钮 { startService(mIntent); // 启动指定意图的服务 } else if (v.getId() == R.id.btn_stop)// 点击了停止服务按钮 { stopService(mIntent); // 停止指定意图的服务 } } public static void showText(String desc) { if (tv_normal != null) { mDesc = String.format("%s%s %s\n", mDesc, DateUtil.getNowDateTime("HH:mm:ss"), desc); tv_normal.setText(mDesc); } } }
NormalService
package com.example.myapplication; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class NormalService extends Service { private static final String TAG = "NormalService"; private void refresh(String text) { Log.d(TAG, text); MainActivity7.showText(text); } @Override public void onCreate() { // 创建服务 super.onCreate(); refresh("onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startid) // 启动服务,Android2.0以上使用 { Log.d(TAG, "测试服务到此一游!"); refresh("onStartCommand. flags=" + flags); return START_STICKY; } @Override public void onDestroy() // 销毁服务 { super.onDestroy(); refresh("onDestroy"); } @Override public IBinder onBind(Intent intent) // 绑定服务。普通服务不存在绑定和解绑流程 { refresh("onBind"); return null; } @Override public void onRebind(Intent intent) // 重新绑定服务 { super.onRebind(intent); refresh("onRebind"); } @Override public boolean onUnbind(Intent intent) // 解绑服务 { refresh("onUnbind"); return true; // 返回false表示只能绑定一次,返回true表示允许多次绑定 } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <!-- 允许前台服务(Android 9.0之后需要) --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 允许访问互联网 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 允许修改徽章(角标数字) --> <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <activity android:name=".MainActivity7" android:exported="false" /> <service android:name=".NormalService" android:enabled="true" android:exported="true" /> <service android:name=".MusicService" android:enabled="true" android:exported="true" /> <activity android:name=".MainActivity6" android:exported="false" /> <activity android:name=".MainActivity5" android:exported="false" /> <activity android:name=".MainActivity4" android:exported="false" /> <activity android:name=".MainActivity3" android:exported="false" /> <activity android:name=".MainActivity2" android:exported="false" /> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
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; } }
=====================================================================================