バックグラウンドサービスからDependencyServiceをコールする方法 | Xamarin.Forms
- 2017/05/10
- 15:06
今回は、以前にご紹介いたしましたバックグラウンドサービスの記事の続きとなります。バックグラウンドサービスからPCLやDependencyServiceのコードを実行する方法についてご紹介いたします。DependencyServiceをコールすることにより、バックグラウンドからデータベースへの更新ができたり、処理を共通化できるなどメリットがたくさんあります。
尚、Android でのバックグラウンドサービスは以下の記事でご紹介しています。
・OS起動時に自動実行するサービスの作成方法
iOSのバックグラウンド処理は以下の記事でご紹介しています。
・バックグラウンドタスクを実行する方法
・Background Fetch を実行する方法
前提条件
・Windows10
・Visual Studio 2015 Community Update3
・Xamarin 4.3.0.784 (NuGet Xamarin.Forms 2.3.4.224)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.4.0.123
1.PCLの記述
ループの中の処理を記述します。ここではDependencyServiceをコールしています。BackgroundThread.cs
public static class BackgroundThread
{
public static void Main()
{
while (true)
{
DependencyService.Get<INotificationService>().On("BackgroundThread.Main Alive", "BackgroundThread.Main通知テストです。");
await Task.Delay(30000);
}
}
}
※DependencyServiceのNotificationServiceについては以下の記事にてご紹介しています。
http://itblogdsi.blog.fc2.com/blog-entry-145.html
2.Androidでの記述方法
BroadcastReceiver.csから呼ばれるクラスです。Xamarinを有効化するために、Xamarin.Forms.Forms.Initをコールしています。引数には自身のインスタンスと新しいバンドルのインスタンスでOKです。BackgroundService.cs
[Service(Name = "com.CompanyName.AppName.BackgroundService", Exported = false, Process = ":BackgroundService")]
public class BackgroundService : Service
{
public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
Thread t = new Thread(() =>
{
//Xamarinを有効化
var bundle = new Bundle();
global::Xamarin.Forms.Forms.Init(this, bundle);
//PCLのクラスを実行
AppName.BackgroundThread.Main();
});
t.Start();
return StartCommandResult.Sticky;
}
}
3.iOSでの記述方法
バックグラウンドタスクとBackgroud Fetch の両方からthis.BackgroundService()メソッドをコールすることで処理を共通化しており、共通処理の中でXamarinを有効にするXamarin.Forms.Forms.Initをコールしています。AppDelegate.cs
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
private nint _bgTaskId = 0;
/// <summary>
/// バックグラウンドタスクを開始
/// </summary>
/// <param name="app"></param>
public override void DidEnterBackground(UIApplication app)
{
base.DidEnterBackground(app);
try
{
if (_bgTaskId != 0) return;
_bgTaskId = UIApplication.SharedApplication.BeginBackgroundTask(() => { });
this.BackgroundService();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
}
}
public override void PerformFetch(UIApplication app, Action<UIBackgroundFetchResult> completionHandler)
{
try
{
this.BackgroundService();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
}
finally
{
completionHandler(UIBackgroundFetchResult.NewData);
}
}
private async void BackgroundService()
{
await Task.Run(() =>
{
//Xamarinを有効化
global::Xamarin.Forms.Forms.Init();
//PCLのクラスを実行
AppName.BackgroundThread.Main();
}).ConfigureAwait(false);
}
}
Xamarin.Forms.Forms.Initを事前に呼び出すことでアプリ内の処理が使用できるようになります。ただし、AndroidではDependencyService内の処理でContext(Forms.Context)を使用している箇所は正しく動作しません。別途ActivityまたはContextを受け渡しして記述してください。
当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html
- 関連記事
-
- Androidで画像のサイズを指定して縮小する方法 | Xamarin.Forms
- ListViewなどのImageを多く表示するとjava.lang.OutOfMemoryErrorが発生する場合の対応方法 | Xamarin.Forms
- バックグラウンドサービスからDependencyServiceをコールする方法 | Xamarin.Forms
- メールを送信する方法 | Xamarin.Forms
- Error Code 403 : Version XX of this app can not be downloaded by any devices as they will all receive APKs with higher version codes. | Xamarin.Forms
ListViewなどのImageを多く表示するとjava.lang.OutOfMemoryErrorが発生する場合の対応方法 | Xamarin.Forms ホーム
メールを送信する方法 | Xamarin.Forms