Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Xamarin使用IsolatedProcess=true启动新服务_C#_Xamarin_Xamarin.forms_Service - Fatal编程技术网

C# Xamarin使用IsolatedProcess=true启动新服务

C# Xamarin使用IsolatedProcess=true启动新服务,c#,xamarin,xamarin.forms,service,C#,Xamarin,Xamarin.forms,Service,所以我有两个问题需要你帮忙解决 首先,当我设置IsolatedProcess=trueOnStartCommand从不触发 第二个问题是,当我启动通知时,由于某种原因,我的通知中出现了$projectname$ 这是我的服务代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Android.App; using

所以我有两个问题需要你帮忙解决

首先,当我设置
IsolatedProcess=true
OnStartCommand
从不触发

第二个问题是,当我启动通知时,由于某种原因,我的通知中出现了
$projectname$

这是我的服务代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace Comic.Viewer.Droid.Services
{
    [Service(IsolatedProcess = true, Label = "ComicViewer.ChapterNotifier.Service")]
    public class ChapterNotifier : Android.App.Service
    {
        public override IBinder OnBind(Intent intent)
        {
            throw new NotImplementedException();
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            var NotificationHelper = new NotificationHelper(MainActivity.CurrentActivity);


            intent.AddFlags(ActivityFlags.ClearTop);



            while (true)
            {
                var favs = DataStore.Db.GetFavorits(DataStore.AppSettings.CurrentUser.Id);

                foreach (var item in favs)
                {
                    var update = item.Translator == Modols.Translator.W_World_Translator ?
                                 DataStore.Wuxiaworld.SerieUpdates(item.Query) : (item.Translator == Modols.Translator.Boxnovel ?
                                 DataStore.Boxnovel.SerieUpdates(item.Query) : DataStore.NovelOver.SerieUpdates(item.Query));

                    var message = "";
                    if (update.NewChapters > 0)
                    {
                        message += $"{item.SerieName} Has {update.NewChapters} new chapter";

                        var NotificationId = Helper.GetRandomId();
                        var pendingIntent = PendingIntent.GetActivity(MainActivity.CurrentActivity, NotificationId, intent, PendingIntentFlags.Immutable);
                        var nb = NotificationHelper.GetNotification1(GetString(Resource.String.ApplicationName), message, pendingIntent);
                        if (Build.VERSION.SdkInt >= BuildVersionCodes.O) StartForeground(NotificationId, nb.Build());
                        NotificationHelper.Notify(NotificationId, nb);
                    }
                }
                Thread.Sleep(18000000);
            }

        }
    }
}
下面是我如何开始我的服务

public void StartService()
        {

            var intent = new Intent(_context, typeof(ChapterNotifier));
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
                _context.StartForegroundService(intent);
            else
                _context.StartService(intent);
        }

要解决启动应用程序时服务冻结的问题,您可以做几件不同的事情

其中一个正在启动任务,而不是阻塞主线程

因此,将您的逻辑封装在如下方法中:

private async Task ReadFavorites(CancellationToken token = default)
{
    while(!token.IsCancellationRequested)
    {
        // your database and notification logic here...
        await Task.Delay(18000000, token);
    }
}
然后在
OnStartCommand
中,您可以使用以下命令启动:

_ = Task.Run(() => ReadFavorites());
如果您想在某个时候停止此服务并取消任务,您可以创建一个
CancellationTokenSource
,并将
CancellationToken
从中传递到方法:

var cts = new CancellationTokenSource();

var token = cts.Token;
然后将此令牌传递到已启动的任务中:

_ = Task.Run(() => ReadFavorites(token), token);
这样,您就可以调用
cts.Cancel()
来取消任何不想再运行的任务


然而,在Android中使用
JobScheduler
API可能会更好地完成类似的操作,因为您在检查之间等待的时间太长了。这样,您就不需要前台服务一直运行并显示通知。

为什么要将其作为一个独立的进程使用?没有理由,除非你想运行一些与你自己的应用程序隔离的不安全代码。也适用于$projectname$对象。检查您的AndroidManifest并查看它对应用程序名称使用的值。也许是某个你没有填写的占位符。Thread.Sleep(18000000);冻结我的应用程序,因此我想为该服务创建一个新线程。至于$projectname$是我升级xamarin.form后遇到的某种bug。我以前没有遇到过这个问题这是一个很好的解决方案,但我仍然想知道为什么
隔离进程
不起作用,可能是因为您没有指定它应该在哪个进程中使用
进程
属性运行。您的解决方案非常有效,尽管我仍然不明白为什么隔离进程不起作用,但我仍然为解决方案感到高兴,所以谢谢