安卓期末考點(diǎn)整理

前言

臨近考試蝶缀,根據(jù)老師發(fā)的考試說明和例題整理出如下的復(fù)習(xí)資料

安卓的平臺(tái)架構(gòu)

安卓的基本架構(gòu)

由下至上分別是:

  1. linux內(nèi)核
  2. 庫(kù)
  3. Android運(yùn)行時(shí)
  4. 應(yīng)用程序框架
  5. 應(yīng)用程序

下面簡(jiǎn)述每層的作用:

linux內(nèi)核

Android 平臺(tái)的基礎(chǔ)是 Linux 內(nèi)核大审。例如,Android Runtime (ART) 依靠 Linux 內(nèi)核來執(zhí)行底層功能,例如線程和低層內(nèi)存管理。
使用 Linux 內(nèi)核可讓 Android 利用主要安全功能,并且允許設(shè)備制造商為著名的內(nèi)核開發(fā)硬件驅(qū)動(dòng)程序。

Android運(yùn)行時(shí)

Android 包括了一個(gè)核心庫(kù)舱呻,該核心庫(kù)提供了JAVA編程語(yǔ)言核心庫(kù)的大多數(shù)功能。

程序庫(kù)

Android包含一些C/C++庫(kù)悠汽,這些庫(kù)能被Android系統(tǒng)中不同的組件使用箱吕。它們通過Android應(yīng)用程序框架為開發(fā)者提供服務(wù)。

應(yīng)用程序框架

Android系統(tǒng)提供給應(yīng)用開發(fā)者的本身就是一個(gè)框架柿冲,所有的應(yīng)用開發(fā)都必須遵守這個(gè)框架的原則茬高。

應(yīng)用程序

所有的應(yīng)用程序都是使用JAVA語(yǔ)言編寫的,每一個(gè)應(yīng)用程序由一個(gè)或者多個(gè)活動(dòng)組成假抄,活動(dòng)必須以Activity類為超類怎栽,活動(dòng)類似于操作系統(tǒng)上的進(jìn)程,但是活動(dòng)比操作系統(tǒng)的進(jìn)程要更為靈活宿饱,與進(jìn)程類似的是熏瞄,活動(dòng)在多種狀態(tài)之間進(jìn)行切換。

安卓的四大組件

  1. 活動(dòng)----Activity

他是一種可以包含用戶界面的組件谬以,主要用于和用戶進(jìn)行交互

  1. 服務(wù)----Service

Service是在一段不定的時(shí)間運(yùn)行在后臺(tái)强饮,不和用戶交互應(yīng)用組件。

  1. 廣播----Broadcast Receiver
  2. 內(nèi)容提供者----Content Provider

用于在不同的應(yīng)用程序之間實(shí)現(xiàn)數(shù)據(jù)共享的功能为黎。提供了一套完整的機(jī)制邮丰,允許一個(gè)程序訪問倆一個(gè)程序中的數(shù)據(jù),同時(shí)還能保證被訪問數(shù)據(jù)的安全性

安卓清單文件的作用

  • 它為應(yīng)用指定Java包铭乾。此包名稱唯一標(biāo)識(shí)應(yīng)用
  • 它描述了應(yīng)用的不同組件剪廉。它指定了實(shí)現(xiàn)這些組件并公布它們的功能。這些聲明幫助Android系統(tǒng)識(shí)別和組件及它們可以啟動(dòng)的條件炕檩。
  • 它指定應(yīng)用訪問API的受保護(hù)部分和其他應(yīng)用交換所需的權(quán)限斗蒋。
  • 它指定應(yīng)用可在其上運(yùn)行的API的最低級(jí)別
  • 它指定鏈接應(yīng)用所必須依據(jù)的庫(kù)

常用的布局和控件以及其使用方法

四種最基本的布局

總共有四種最基本的布局,分別是:

線性布局(LinearLayout)
相對(duì)布局(RelativeLayout)
幀布局(FrameLayout)
百分比布局

因?yàn)榭荚囌f明里面只有兩種,所以接下來只介紹兩種

LinearLayout(線性布局)

  • 指定各個(gè)節(jié)點(diǎn)的排列方向
android:orientation="horizontal"
  • 設(shè)置右對(duì)齊
android:layout_gravity="right"
  • 當(dāng)豎直布局時(shí)笛质,只能左右對(duì)齊和水平居中吹泡,頂部底部對(duì)齊豎直居中無(wú)效
  • 當(dāng)水平布局時(shí),只能頂部底部對(duì)齊和豎直居中
  • 使用match_parent時(shí)注意不要把其他組件頂出去
  • 線性布局非常重要的一個(gè)屬性:權(quán)重
android:layout_weight="1"

權(quán)重設(shè)置的是按比例分配剩余的空間

RelativeLayout
  • 組件默認(rèn)左對(duì)齊经瓷、頂部對(duì)齊
  • 設(shè)置組件在指定組件的右邊
android:layout_toRightOf="@id/tv1"
  • 設(shè)置在指定組件的下邊
android:layout_below="@id/tv1"
  • 設(shè)置右對(duì)齊父元素
android:layout_alignParentRight="true"
  • 設(shè)置與指定組件右對(duì)齊
android:layout_alignRight="@id/tv1"

常用的控件

TextView、EditText洞难、Button舆吮、ImageButton、ToggleButton、RadioButton色冀、RadioGroup潭袱、Checkbox、Spinner锋恬、ListView屯换、ImageView、WebView与学、ScrollView

重要的屬性有:

android:id:指明控件id
android:layout_width::指明控件的寬度
android:layout_height:指明控件的高度

相關(guān)控件及其使用方法可以參考
Android筆記---常用控件以及用法

創(chuàng)建一個(gè)活動(dòng)(Activity)的步驟

  1. 創(chuàng)建活動(dòng)彤悔,編寫自己的Acivity類,繼承Activity類
  2. 將UI與活動(dòng)關(guān)聯(lián)索守。調(diào)用setContentView方法
  3. 在清單文件中注冊(cè)活動(dòng)

活動(dòng)(Activity)的生命周期

活動(dòng)的狀態(tài)

  1. 運(yùn)行狀態(tài)

當(dāng)一個(gè)活動(dòng)處于返回棧的棧頂晕窑,也就是在屏幕的前臺(tái)顯示時(shí),稱為運(yùn)行狀態(tài)

  1. 暫停狀態(tài)

如果一個(gè)Activity失去焦點(diǎn)(不在棧頂)卵佛,但是依然可見(一個(gè)新的非全屏的Activity杨赤,例如一個(gè)對(duì)話框形式的活動(dòng),或者一個(gè)透明的Activity 被放置在棧頂)截汪,叫做暫停狀態(tài)(Paused)

  1. 停止?fàn)顟B(tài)

如果一個(gè)Activity被另外的Activity完全覆蓋掉(不在棧頂且不可見)疾牲,叫做停止?fàn)顟B(tài)(Stopped)

  1. 銷毀狀態(tài)(了解)
    當(dāng)一個(gè)活動(dòng)從返回棧移除之后就變成的銷毀狀態(tài)

活動(dòng)的7個(gè)生命周期的方法

7個(gè)生命周期的方法

活動(dòng)的生命周期的圖

活動(dòng)的生命周期

Intent的使用

  1. 顯式Intent
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);

上述代碼的作用是打開活動(dòng)SecondActivity

  1. 隱式Intent

相比隱式Intent,隱式Intent并不明確指出想要啟動(dòng)哪一個(gè)活動(dòng)衙解,而是指定了一系列抽象的action和category等信息阳柔,然后交由系統(tǒng)去分析這個(gè)Intent,并找到合適的活動(dòng)去啟動(dòng)

使用隱式Intent
首先打開AndroidManifest.xml丢郊,添加代碼:

<activity android:name=".Main2Activity">
        <intent-filter>
            <action android:name="com.lyy.intent.ACTION_START" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
</activity>

指定好當(dāng)前活動(dòng)可以相應(yīng)的action和category
回到MainActivity.java中

Intent intent=new Intent("com.lyy.intent.ACTION_START");
startActivity(intent);

將Intent傳入我們自定義的action字符串即可

  1. Intent的系統(tǒng)action


    Android系統(tǒng)廣播action
  2. 利用Intent傳值的兩種方式

利用Intent直接傳值
MainActivity.java —— 負(fù)責(zé)傳遞數(shù)據(jù)

Intent intent1=new Intent(MainActivity.this,Main2Activity.class);
intent1.putExtra("extra","hello");
startActivity(intent1);

Main2Activity —— 負(fù)責(zé)接收數(shù)據(jù)

Intent intent = getIntent();
String data = intent.getStringExtra("extra");
Log.d(TAG, "onCreate: " + data);

利用Bundle和Intent傳值
MainActivity.java —— 負(fù)責(zé)傳遞數(shù)據(jù)

Intent intent2 = new Intent(MainActivity.this, Main2Activity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "lyy");
bundle.putInt("age", 18);
bundle.putString("address", "China");
intent2.putExtras(bundle);
startActivity(intent2);

Main2Activity —— 負(fù)責(zé)接收數(shù)據(jù)

Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String nameString = bundle.getString("name");
int age = bundle.getInt("age");
String addressString = bundle.getString("address");

原生方法操作SQLite數(shù)據(jù)庫(kù)

創(chuàng)建一個(gè)類用于繼承SQLiteOpenHelper類盔沫,并重寫兩個(gè)方法onCreate()和onUpgrade()方法用于創(chuàng)建和升級(jí)數(shù)據(jù)庫(kù),代碼示例如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table Book(" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)";

    public static final String CREATE_CATEGORY = "create table Category(" +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)";

    private Context mContext;

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }
}

對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行增刪改查(CRUD)操作

添加數(shù)據(jù)

先實(shí)例化之前創(chuàng)建的DatabaseHelper對(duì)象枫匾,并調(diào)用其getWritableDatabase()方法架诞,設(shè)置該數(shù)據(jù)庫(kù)可寫

SQLiteDatabase db = databaseHelper.getWritableDatabase();

隨后創(chuàng)建ContentValues對(duì)象,用來添加數(shù)據(jù)

ContentValues values = new ContentValues();
//開始組裝第一組數(shù)據(jù)
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);

最后執(zhí)行db數(shù)據(jù)庫(kù)的insert()方法

db.insert("Book", null, values);//插入第一條數(shù)據(jù)

更新數(shù)據(jù)

創(chuàng)建ContentValues對(duì)象干茉,并組裝要更新的數(shù)據(jù)

ContentValues values1 = new ContentValues();
values1.put("price", 10.99);

調(diào)用update()方法

db.update("Book", values1, "name = ?", new String[]{"The Da Vinci Code"});

第一個(gè)參數(shù)指定表名谴忧,第二個(gè)指定要更新的數(shù)據(jù),第三個(gè)指定要更新的行角虫,如果沒有沾谓,則默認(rèn)更新所有行。

刪除數(shù)據(jù)

直接調(diào)用delete方法即可

db.delete("Book", "pages > ?", new String[]{"500"});

查詢數(shù)據(jù)(最復(fù)雜)

通過調(diào)用db的query()方法戳鹅,獲得一個(gè)cursor對(duì)象

//查詢Book表中的所有數(shù)據(jù)
Cursor cursor = db.query("Book", null, null, null, null, null, null);

在這里需要傳入7個(gè)參數(shù)均驶,作用分別如下:


query的7個(gè)參數(shù)及其作用

然后在對(duì)cursor對(duì)象進(jìn)行遍歷,獲得查詢到的值

while (cursor.moveToFirst()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                }

最后枫虏,一定記得要回收cursor對(duì)象

cursor.close();

文件存儲(chǔ)

寫文件

public void save() {
        String data = "Data to save";
        try {
            FileOutputStream fos = openFileOutput("data", Context.MODE_PRIVATE);
            fos.write(data.getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

讀文件

public void load() {
        String fileName = "abc.txt";
        try {
            FileInputStream fis = openFileInput(fileName);
            byte[] reader = new byte[fis.available()];
            if (fis.read(reader) != -1) {
                String data = new String(reader);
                System.out.println(data);
            }
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

共享首選項(xiàng)(SharedPreferences)

利用鍵值對(duì)的方式來存儲(chǔ)數(shù)據(jù)妇穴,文件都是存放在/data/data/<packagename>/shared_prefs/目錄下的爬虱,主要提供了三種方式用于得到SharedPreferences對(duì)象


三種方式獲得SharePreferences對(duì)象

內(nèi)容提供器

主要用于在不同的應(yīng)用程序之間實(shí)現(xiàn)數(shù)據(jù)的共享功能。目前是Android實(shí)現(xiàn)跨程序共享數(shù)據(jù)的標(biāo)準(zhǔn)方式腾它。一般有兩種:
1.使用現(xiàn)有的內(nèi)容提供其來讀取和操作相應(yīng)程序中的數(shù)據(jù)

  1. 創(chuàng)建自己的內(nèi)容提供器給我們的程序的數(shù)據(jù)提供外部訪問接口

使用本機(jī)內(nèi)容提供者

Android平臺(tái)提供了一些本機(jī)內(nèi)容提供者有:瀏覽器跑筝、聯(lián)系人、通話記錄瞒滴、媒體存儲(chǔ)曲梗、設(shè)置。
聯(lián)系人內(nèi)容提供者的URI各部分:

  • content://contacts/people/20
  • content:// 指定數(shù)據(jù)受內(nèi)容提供者控制妓忍。它是標(biāo)準(zhǔn)前綴
  • contacts:指原生Contacts內(nèi)容提供者
  • people指contacts列表可用記錄
  • 20指Contacts列表中的第二十條記錄虏两。它是指定記錄的ID
  • 使用getContentResolver()方法獲取ContentResolver對(duì)象,通過該對(duì)象的以下方法訪問內(nèi)容提供者
public final Uri insert(Uri url, ContentValues values)
public final int delete(Uri url, String where, String[] selectionArgs)
public final int update(Uri uri, ContentValues values, String where,String[] selectionArgs)
public final Cursor query(Uri uri, String[] projection,String selection, String[] selectionArgs, String sortOrder)

使用自定義內(nèi)容提供器

創(chuàng)建內(nèi)容提供器

新建一個(gè)類去繼承ContentProvider单默,并重寫其6個(gè)方法碘举,代碼如下:

public class MyProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        return false;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        return null;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
}
  1. onCreate()
    初始化內(nèi)容提供器的時(shí)候調(diào)用。通常會(huì)在這里完成對(duì)數(shù)據(jù)庫(kù)的創(chuàng)建和升級(jí)等操作搁廓,
    返回 true 表示內(nèi)容提供器初始化成功引颈,返回 false 則表示失敗。注意境蜕,只有當(dāng)存在
    ContentResolver 嘗試訪問我們程序中的數(shù)據(jù)時(shí)蝙场,內(nèi)容提供器才會(huì)被初始化。
  2. query()
    從內(nèi)容提供器中查詢數(shù)據(jù)粱年。使用 uri 參數(shù)來確定查詢哪張表售滤,projection 參數(shù)用于確
    定查詢哪些列,selection 和 selectionArgs 參數(shù)用于約束查詢哪些行台诗,sortOrder 參數(shù)用于
    對(duì)結(jié)果進(jìn)行排序完箩,查詢的結(jié)果存放在 Cursor 對(duì)象中返回。
  3. insert()
    向內(nèi)容提供器中添加一條數(shù)據(jù)拉队。使用 uri 參數(shù)來確定要添加到的表弊知,待添加的數(shù)據(jù)
    保存在 values 參數(shù)中。添加完成后粱快,返回一個(gè)用于表示這條新記錄的 URI秩彤。
  4. update()
    更新內(nèi)容提供器中已有的數(shù)據(jù)。使用 uri 參數(shù)來確定更新哪一張表中的數(shù)據(jù)事哭,新數(shù)
    據(jù)保存在 values 參數(shù)中漫雷,selection 和 selectionArgs 參數(shù)用于約束更新哪些行,受影響的
    行數(shù)將作為返回值返回鳍咱。
  5. delete()
    從內(nèi)容提供器中刪除數(shù)據(jù)降盹。使用 uri 參數(shù)來確定刪除哪一張表中的數(shù)據(jù),selection
    和 selectionArgs 參數(shù)用于約束刪除哪些行谤辜,被刪除的行數(shù)將作為返回值返回澎现。
  6. getType()
    根據(jù)傳入的內(nèi)容 URI 來返回相應(yīng)的 MIME 類型仅胞。

指定內(nèi)容提供者的URI

public class MyProvider extends ContentProvider {

    public static final int TABLE1_DIR = 0;
    public static final int TABLE1_ITEM = 1;
    public static final int TABLE2_DIR = 2;
    public static final int TABLE2_ITEM = 3;
    private static UriMatcher uriMatcher;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
        uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM);
        uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM);
        uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);
    }

    ..........

}

實(shí)現(xiàn)查詢方法

public class MyProvider extends ContentProvider {
    ..........

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        switch (uriMatcher.match(uri)) {
            case TABLE1_DIR:
                // 查詢table1表中的所有數(shù)據(jù)
                break;
            case TABLE1_ITEM:
                // 查詢table1表中的單條數(shù)據(jù)
                break;
            case TABLE2_DIR:
                // 查詢table2表中的所有數(shù)據(jù)
                break;
            case TABLE2_ITEM:
                // 查詢table2表中的單條數(shù)據(jù)
                break;
            default:
                break;
        }
        return null;
    }
    ....
}

處理對(duì)MINE類型數(shù)據(jù)的請(qǐng)求

public class MyProvider extends ContentProvider {

    ...........

    @Nullable
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case TABLE1_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.app.provider. table1 ";
            case TABLE1_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.app.provider. table1 ";
            case TABLE2_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.app.provider. table2 ";
            case TABLE2_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.app.provider. table2 ";
            default:
                break;
        }
        return null;
    }
................
}

注冊(cè)自定義內(nèi)容提供器

<provider
      android:name="com.example.databasetest.DatabaseProvider"
      android:authorities="com.example.databasetest.provider" >
</provider>

廣播接收者(BroadcastReceiver)

廣播分為兩種:普通廣播和有序廣播

  1. 普通廣播

完全異步執(zhí)行的廣播,在廣播發(fā)出后剑辫,所有的廣播接收器幾乎在同一時(shí)刻都會(huì)受到這條廣播,沒有先后順序之分渠欺,無(wú)法被截?cái)嗝帽危瘦^高


普通廣播圖示
  1. 有序廣播

同步執(zhí)行的廣播,在廣播發(fā)出后挠将,同一時(shí)刻只會(huì)有一個(gè)廣播接收器可以收到消息胳岂,且只有當(dāng)該廣播接收器中的邏輯執(zhí)行完畢后,這條廣播才會(huì)繼續(xù)傳遞下去舔稀,有先后順序之分乳丰,可以被截?cái)唷?/p>

有序廣播圖示

注冊(cè)廣播接收器的方式有兩種:

  1. 動(dòng)態(tài)注冊(cè)

在代碼中注冊(cè),新建一個(gè)類内贮,并讓其繼承BroadcastReceiver類产园,同時(shí)重新其父類中的onReceive()方法即可,這樣當(dāng)有廣播到來的時(shí)候夜郁,onReceive()方法便會(huì)得到執(zhí)行,同時(shí)需要主活動(dòng)中進(jìn)行廣播的注冊(cè)什燕,因?yàn)槿淌窃诖a中運(yùn)行,靈活性強(qiáng)竞端,便被成為動(dòng)態(tài)注冊(cè)屎即,示例如下:

private class NetWorkChangeReceiverextends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // do something......
        }
    }

在onCreate()方法中執(zhí)行:

intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netWorkChangeReceiver = new NetWorkChangeReceiver();
registerReceiver(netWorkChangeReceiver, intentFilter);

在onDestory()方法中執(zhí)行:

unregisterReceiver(netWorkChangeReceiver);//注銷廣播
  1. 靜態(tài)注冊(cè)

和動(dòng)態(tài)注冊(cè)相同的是,靜態(tài)注冊(cè)也需要?jiǎng)?chuàng)建一個(gè)類去繼承BroadcastReceiver類并實(shí)現(xiàn)其中的onReceive()方法事富,但是注冊(cè)的過程被放到了AndroidManifest.xml文件中了技俐,示例如下:

MyBroadcastReceiver.java

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
    }
}

AndroidManifest.xml

<receiver
     android:name=".MyBroadcastReceiver"
     android:enabled="true"
     adroid:exported="true">
       <intent-filter>
           <action android:name="com.lyy.broadcast.MY_BROADCAST" />
       </intent-filter>
</receiver>

動(dòng)態(tài)注冊(cè)和靜態(tài)注冊(cè)的區(qū)別:

動(dòng)態(tài)注冊(cè)不是常駐型廣播,也就是說廣播跟隨程序的生命周期统台。
靜態(tài)注冊(cè)是常駐型雕擂,也就是說當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來饺谬,程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行

服務(wù)

創(chuàng)建一個(gè)服務(wù)

新建一個(gè)類MyService集成Service捂刺,并重寫其onBind()方法即可

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

當(dāng)然,最為四大組件之一的Service募寨,服務(wù)在創(chuàng)建的時(shí)候需要在AndroidManifest.xml文件中進(jìn)行注冊(cè)才能生效

<service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
</service>

啟動(dòng)一個(gè)服務(wù)

調(diào)用startService()方法即可啟動(dòng)服務(wù)族展,傳入一個(gè)intent參數(shù)即可

Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);

關(guān)閉一個(gè)服務(wù)

調(diào)用stopService()方法即可

Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);

綁定一個(gè)服務(wù)

  1. 定義一個(gè)內(nèi)部類,該內(nèi)部類實(shí)現(xiàn)接口”ServiceConnection”拔鹰,同時(shí)實(shí)現(xiàn)接口里的兩個(gè)方法:”onServiceConnection”(在這個(gè)方法方法體里得到Binder對(duì)象仪缸,由該對(duì)象就能得到服務(wù)實(shí)例)、”onServiceDisConnection”(當(dāng)服務(wù)被意外斷開列肢,系統(tǒng)將會(huì)回調(diào)這個(gè)方法)恰画。
  2. 分別創(chuàng)建服務(wù)類變量宾茂、內(nèi)部類變量(內(nèi)部類變量需要實(shí)例化),在”onServiceConnection”方法里面用得到的服務(wù)實(shí)例將服務(wù)類變量實(shí)例化
  3. 在需要綁定服務(wù)的地方拴还,調(diào)用bindService()方法跨晴,將內(nèi)部類變量傳入。
public class MainActivity extends Activity implements View.OnClickListener {  
    //第二步:創(chuàng)建內(nèi)部類變量以及服務(wù)類的變量  
    //同時(shí)實(shí)例化內(nèi)部類變量  
    private MService mService = null;    
    private MServiceConnection mServiceConnection =   
    new MServiceConnection();  
   
    //窗體的初始化方法  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        findViewById(R.id.bt_bind_the_service)  
         .setOnClickListener(this);        
    }  
    //點(diǎn)擊事件響應(yīng)函數(shù)  
    @Override  
    public void onClick(View v) {  
  
        switch (v.getId()){  
            case R.id.bt_bind_the_service:  
                Intent intent =  
             new Intent(MainActivity.this, MService.class);  
                //第三步:綁定服務(wù)那個(gè)時(shí)候?qū)⒔涌诘膶?shí)例傳入  
                bindService(intent, mServiceConnection,  
                  Context.BIND_AUTO_CREATE);  
                break;  
        }  
    }  
  
    //第一步:定義一個(gè)內(nèi)部類去實(shí)現(xiàn)接口”ServiceConnection”  
  
    class MServiceConnection implements ServiceConnection{  
        //這個(gè)方法里面那個(gè)service  
        //就是服務(wù)類里面的onBind()方法所返回的IBinder變量了  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
        //還是第二步:將服務(wù)類的變量實(shí)例化:  
            //將IBinder向下轉(zhuǎn)型  
            MService.MyBinder myBinder = (MService.MyBinder)service;  
            //調(diào)用公有方法就能獲得服務(wù)類的實(shí)例  
            mService = myBinder.getService();  
            Log.i("test","連接服務(wù)");  
        }  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
            Log.i("test", "意外斷開");  
        }  
    }  
  
}  

解綁一個(gè)服務(wù)

相對(duì)于綁定一個(gè)服務(wù)和活動(dòng)來說片林,解除服務(wù)和活動(dòng)之間的綁定就顯得容易很多端盆,只需要執(zhí)行unbindService()方法,并傳入一個(gè)ServiceConnection()對(duì)象即可费封。

unbindService(connection);

服務(wù)的生命周期

詳見 Android:Service生命周期最全面解析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末焕妙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弓摘,更是在濱河造成了極大的恐慌焚鹊,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件韧献,死亡現(xiàn)場(chǎng)離奇詭異末患,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)势决,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門阻塑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人果复,你說我怎么就攤上這事陈莽。” “怎么了虽抄?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵走搁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我迈窟,道長(zhǎng)私植,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任车酣,我火速辦了婚禮曲稼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘湖员。我一直安慰自己贫悄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布娘摔。 她就那樣靜靜地躺著窄坦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸭津,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天彤侍,我揣著相機(jī)與錄音,去河邊找鬼逆趋。 笑死盏阶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闻书。 我是一名探鬼主播般哼,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼惠窄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起漾橙,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杆融,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后霜运,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脾歇,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年淘捡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藕各。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焦除,死狀恐怖激况,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膘魄,我是刑警寧澤乌逐,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站创葡,受9級(jí)特大地震影響浙踢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灿渴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一洛波、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骚露,春花似錦蹬挤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至够话,卻和暖如春蓝翰,著一層夾襖步出監(jiān)牢的瞬間光绕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工畜份, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诞帐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓爆雹,卻偏偏與公主長(zhǎng)得像停蕉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钙态,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,110評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)慧起、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,102評(píng)論 4 62
  • 轉(zhuǎn)自 1. 什么是Activity? 四大組件之一,一般的,一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)activity setCon...
    joe1632閱讀 1,400評(píng)論 0 7
  • 以前別人問我册倒,最喜歡吃什么蚓挤,我說是豆豉鯪魚罐頭,我喜歡那種口味十年了驻子,很難戒的灿意。對(duì)了,你真的要嫁給別人嗎崇呵? 對(duì)啊缤剧,...
    王蕾愛粽子閱讀 715評(píng)論 0 0
  • 會(huì)給三星半的電影。沒有大的出彩域慷,也沒有大的出錯(cuò)荒辕。故事的講述會(huì)有打動(dòng)人心的地方,比如男主糾結(jié)要不要叫醒女主芒粹,也有太過...
    玩兒_溫暖閱讀 167評(píng)論 0 0