Android(Xamarin)之旅(五)

原文: Android(Xamarin)之旅(五)

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手機上測試了,徹底可行,哈哈。看虛擬機效果。直接點擊按鈕。

  是否是感受本身很帥氣的樣子,其實我就是這麼想的。

  看到這篇文章的妹紙,漢字,點一下您那可愛的小手,給推薦一下,小弟這廂有禮了。

相關文章
相關標籤/搜索