2016年1月23日,北京迎來了很痛苦的一天,凍死寶寶了,一天都沒有出我本身的小黑屋,在這屋子裏自娛自樂。不知道大家呢html
對於android的四大基本組件(Activity、Service、Broadcast Receiver、Content Provider),android
前面已經介紹了Activity,最基本的活動單元,任何一個活動的處理,都須要他,前面介紹的對話框、佈局、提示消息、基本內容設置等等。Broadcase Receiver,廣播,主要是用於異步接受Intent(信使),在四的時候有一個小例子,今天咱們來講一下 Service。數據庫
1、Servicedom
Service能夠在和多場合的應用中使用,好比播放多媒體的時候用戶啓動了其餘Activity這個時候程序要在後臺繼續播放,好比檢測SD卡上文件的變化,再或者在後臺記錄你地理信息位置的改變等等,總之服務嘛,老是藏在後頭的。Service是在一段不定的時間運行在後臺,不和用戶交互應用組件。每一個Service必須在manifest中 經過<service>來聲明。能夠經過contect.startservice和contect.bindserverice來啓動。
異步
其中涉及的方法有:ide
OnCreate:只會在服務第一次開啓的時候調用,主要負責一些初始化代碼。
OnStartCommand:每次啓動服務都會調用該方法,可能來自StartService或者由系統重啓。通常負責開啓須要長時間的任務。而且該方法還要返回StartCommandResult類型的枚舉,該返回值將影響系統重啓該服務的細節。
OnDestroy:當服務使用StopSelf或者StopService時調用,主要用來釋放資源等。佈局
須要說明的一點就是在Java裏面寫的時候,咱們須要在AndroidManifest.xml裏面添加服務,可是,在Xamarin裏面,不須要這麼複雜,咱們直接在開頭加上說明[Service]就能夠了。其實就像一個簡單的過濾器同樣。其中過濾器在前面的隱式意圖中已經提到。post
[Service] public class MainService : Service { }
新建一個項目,而後再項目中添加一個類,直接加在根目錄下面就能夠MainService,而後繼承Service,而且去實現他。性能
首先要實現的是OnBind方法,這個方法是必須的,因此咱們直接return null就能夠。測試
public override IBinder OnBind(Intent intent) { return null; }
而後說說涉及到的方法:OnCreate,這裏的三個方法全都是重寫的,由於,在Android裏面,大部分的方法都是提供的,因此,通常狀況下,咱們須要作的就是實現各類接口。而後各類繼承就能夠。在添加的類裏面添加以下方法。
public override void OnCreate() { base.OnCreate(); Log.Debug("xamarin", "OnCreate_create"); }
OnStartCommand,說一個簡單的技巧,在IDE(VS全球最強大的IDE,沒有之一,哈哈)直接override 方法名,而後直接按一次table鍵。自動補全的哦。
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) { Log.Debug("xamarin", "OnStartCommand_start"); return StartCommandResult.Sticky; }
OnDestroy(),一樣,咱們直接在debug裏面看就能夠。
public override void OnDestroy() { base.OnDestroy(); Log.Debug("xamarin", "OnDestroy_stop"); }
OK,完整的服務代碼咱們已經創建完成了。以下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Android.Util; namespace Test022_Service { [Service] public class MainService : Service { public override void OnCreate() { base.OnCreate(); Log.Debug("xamarin", "OnCreate_create"); } public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) { Log.Debug("xamarin", "OnStartCommand_start"); return StartCommandResult.Sticky; } public override void OnDestroy() { base.OnDestroy(); Log.Debug("xamarin", "OnDestroy_stop"); } public override IBinder OnBind(Intent intent) { return null; } } }
接下來,咱們就來添加界面代碼,在Main.axml裏面添加啓動服務和中止服務的按鈕。(Button便可)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/startService" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="啓動服務" /> <Button android:id="@+id/stopService" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="中止服務" /> </LinearLayout>
對應的後臺,直接啓動便可,在前面的文中提到StartActivity,可是這裏是啓動服務,因此採用StartService便可,一樣,中止服務,也是StopService。
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); Button start = FindViewById<Button>(Resource.Id.startService); start.Click += Start_Click; Button stop = FindViewById<Button>(Resource.Id.stopService); stop.Click += Stop_Click; } private void Stop_Click(object sender, EventArgs e) { Toast.MakeText(this, "中止服務", ToastLength.Short).Show(); StartService(new Intent(this, typeof(MainService))); } private void Start_Click(object sender, EventArgs e) { Toast.MakeText(this, "啓動服務", ToastLength.Short).Show(); StopService(new Intent(this, typeof(MainService))); }
到這裏,咱們的Service已經完成。啓動項目,在虛擬機中查看。
如圖,服務啓動成功的時候怎麼查看呢,這裏只有一個提示信息而已,咱們看一下IDE。
點擊咱們這裏的輸出窗口。
是否是能夠看到了呢,在Service裏面寫的代碼 Log.Debug().
那麼咱們怎麼知道到底那個服務啓動了,那麼咱們來修改一下其中的代碼便可
OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId) { Log.Debug("xamarin", "OnStartCommand_start"); new Thread(() => { Log.Debug("xamarin", startId + "號服務的線程啓動"); Thread.Sleep(1000); Log.Debug("xamarin", startId + "號服務的線程關閉"); StopSelf(startId); }).Start(); return StartCommandResult.Sticky; }
那麼,就有同窗問了,這裏的Thread究竟是用 Java.Lang仍是System.Threading呢,其實在這裏是沒區別的,由於都是啓動一個線程。
OK,運行,查看輸出窗口是否是能夠看到呢。
2、Android數據存儲
在Android中,提供了SQLite數據庫,它是輕量級嵌入式數據庫引擎,它支持 SQL 語言,而且只利用不多的內存就有很好的性能。如今的主流移動設備像Android、iPhone等都使用SQLite做爲複雜數據的存儲引擎,在咱們爲移動設備開發應用程序時,也許就要使用到SQLite來存儲咱們大量的數據,因此咱們就須要掌握移動設備上的SQLite開發技巧,SQLiteDatabase類爲咱們提供了不少種方法,對於添加、更新和刪除來講,咱們均可以使用。
咱們來作一個測試。首先添加一個新的項目。
首先在頁面上添加一個按鈕,用來建立和添加數據,等等。而且添加一個ListView來顯示咱們剛纔添加的數據。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/MyButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="點擊開始添加數據" /> <ListView android:minWidth="25px" android:minHeight="25px" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listView1" /> </LinearLayout>
而後,後臺建立一個ArrayAdapter(數據適配器)去接受這些數據,而且顯示在頁面上。
在這裏若是咱們要拋出異常的時候,最好用Android自帶的SQLiteDatabaseCorruptException,不要用Exception,這個是捕捉不到異常的。
using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; using Android.Widget; using Android.OS; using Android.Database.Sqlite; using Android.Database; namespace Test018 { [Activity(Label = "添加數據庫", MainLauncher = true, Icon = "@drawable/myapk")] public class MainActivity : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // Get our button from the layout resource, // and attach an event to it Button button = FindViewById<Button>(Resource.Id.MyButton); button.Click += delegate { var list = FindViewById<ListView>(Resource.Id.listView1); list.Adapter = CreateLocalDb(); }; } private ArrayAdapter<string> CreateLocalDb() { FindViewById<Button>(Resource.Id.MyButton).SetText(Resource.String.InsertDb); ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1); string file = ""; try { Random rand = new Random(); // //建立數據庫的時候的路徑 // using (SQLiteDatabase db = this.OpenOrCreateDatabase("1.db", FileCreationMode.Private, null)) { db.ExecSQL("create table IF NOT EXISTS T_Person(ID integer primary key autoincrement,Age integer,Name text)"); for (int i = 0; i < 5; i++) { var item = rand.Next(10, 99); db.ExecSQL("insert into T_Person(Age,Name) values (?,?)", new Java.Lang.Object[] { item, "Jeff" + item }); } using (ICursor cursor = db.RawQuery(" select * from T_Person ", null)) { //ADO.Net.reader.Read() 讀取數據 while (cursor.MoveToNext()) { int id = cursor.GetInt(cursor.GetColumnIndex("ID")); int age = cursor.GetInt(cursor.GetColumnIndex("Age")); string name = cursor.GetString(cursor.GetColumnIndex("Name")); adapter.Add(id + ":我是" + name + ",我今年" + age); } } // //獲取到當前的數據庫路徑 // file = this.GetDatabasePath("1.db").Path; } } // //SQLiteDatabaseCorruptException 拋出數據庫異常 // catch (SQLiteDatabaseCorruptException e) { e.ToString(); adapter.Add("添加失敗!"); } adapter.Add(file); return adapter; } } }
如圖,,能夠根據部分註釋去了解他們。咱們運行一下,看下效果。要找路徑的同窗注意最後的哪一句,file = this.GetDatabasePath("1.db").Path;本程序已經在小弟我本身的Android手機上測試了,徹底可行,哈哈。看虛擬機效果。直接點擊按鈕。
是否是感受本身很帥氣的樣子,其實我就是這麼想的。
看到這篇文章的妹紙,漢字,點一下您那可愛的小手,給推薦一下,小弟這廂有禮了。