آموزش ایجاد سرویس در Flutter
سرویس ها عملیاتی هستند که در پس زمینه اجرا می شوند و کارهای مشخصی را در مدت زمان طولانی انجام میدهند.
سرویس مفهومی است که در برنامه نویسی اندروید وجود دارد و قصد داریم که در این مطلب نحوه پیاده سازی آن در Flutter و یاد بگیریم.
بنابراین کدهای این آموزش خیلی با سیستم عامل iOS همخوانی ندارد.
سرویس چیست؟
سرویس ها توسط کامپوننت های دیگر و با صدار زدن متد startService() شروع می شوند.
زمانی که یک سرویس شروع می شود, چرخه حیات آن بستگی به کامپوننتی که آن را درخواست کرده است دارد.
سرویس ها میتوانند بصورت نامحدود در پس زمینه اجرا شوند حتی اگر کامپوننت شروع کننده سرویس از بین برود.
در این حالت سرویس زمانی که کارش به اتمام رسید با دستور stopSelf() خودش را غیرفعال میکند یا توسط کامپوننت دیگری غیر فعال می شود توسط متد stopService().
ساخت سرویس
پروژه فلاتر مورد نظر را در محیط اندروید استودیو باز کنید.
طبق تصویر یک سرویس ایجاد کنید.
وارد سرویسی که ساختید شوید.
در قسمت onStartCommand میتونید بخش منطقی مورد نیازتون و کد نویسی کنید. درواقع کاری که نیاز دارید سرویس برای شما انجام دهد.
برای مثال یک Thread جدید در این قسمت ایجاد میکنیم.
MyThread myThread = new MyThread();
myThread.start();
کدهای کلاس MyThread نیز به شکل زیر است.
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1; i++) {
try {
Thread.sleep(500);
Intent intent = new Intent();
intent.setAction(MY_ACTION);
intent.putExtra("DATAPASSED", i);
_currentValue = i;
sendBroadcast(intent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
stopSelf();
}
}
در این کلاس هر ۵۰۰میلی ثانیه مقداری توسط اینتنت با نام DATAPASSED برگشت داده می شود.
زمانی که این کار تمام شد متد stopSelf صدا زده می شود.
از intent.setAction() برای مشخص کردن اکشن برای اجرا استفاده میکنیم.
دریافت اطلاعات
برای دریافت اطلاعات از سرویس یک BroadcastReceiver در اکتیویتی ایجاد میکنیم.
private class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
int datapassed = arg1.getIntExtra("DATAPASSED", 0);
Toast.makeText(MainActivity.this,
"Value from service !!\n"
+ "Data passed: " + String.valueOf(datapassed),
Toast.LENGTH_LONG).show();
}
}
زمانی که از کلاس BroadcastReceiver ارث بری میکنیم باید متد onReceive را بازنویسی کنیم.
اطلاعات ارسال شده توسط اینتنت با نام DATAPASSED را دریافت میکنیم و توسط پیغام Toast نمایش میدهیم.
سپس در متد onStart باید BroadCastReceiver که ایجاد کردیم را ثبت کنیم.
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(SimpleService.MY_ACTION);
registerReceiver(myReceiver, intentFilter);
همچنین در متد onStop میتونیم BroadCastReceiver را غیرفعال کنیم.
if (myReceiver != null) {
unregisterReceiver(myReceiver);
}
حالا ما نیاز به یک مکانیسمی داریم که این سرویس را از طریق فلاتر فراخوانی کنیم.
برای این کار از قابلیتی به نام MethodChannel استفاده میکنیم.
زمانی که بخواهیم بصورت مستقیم با لایه های مختلف سیستم عامل کار کنیم باید از MethodChannel استفاده شود.
به همین خاطر اکتیویتی خودمون و به شکل زیر تغییر میدهیم.
public class MainActivity extends FlutterActivity implements MethodChannel.MethodCallHandler
متد onMethodCall را نیز به شکل زیر بازنویسی میکنیم.
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
try {
if (call.method.equals("connect")) {
connectToService();
keepResult = result;
} else if (serviceConnected) {
if (call.method.equals("start")) {
String _data = SimpleService.helloFromService();
result.success(_data);
}
} else {
result.error(null, "App not connected to service", null);
}
} catch (Exception e) {
result.error(null, e.getMessage(), null);
}
}
دو متد connect و start را برای استفاده در فلاتر ایجاد میکنیم.
موقع استفاده از connect متد connectToService صدا زده می شود که سرویس را ایجاد میکند.
private void connectToService() {
if (!serviceConnected) {
Intent service = new Intent(this, SimpleService.class);
startService(service);
serviceConnected = true;
} else {
if (keepResult != null) {
keepResult.success(null);
keepResult = null;
}
}
}
همچنین در این متد startService() صدا زده می شود که قبل تر گفتیم کار آن شروع کردن یک سرویس است.
در بخش onCreate اکتیویتی کدهای زیر را قرار دهید.
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(this::onMethodCall);
این متغیر ها را نیز تعریف کنید.
static final String TAG = "Main Activity.....";
static final String CHANNEL = "com.example.services_demo/service";
MyReceiver myReceiver;
MethodChannel.Result keepResult = null;
boolean serviceConnected = false;
مقدار متغیر CHANNEL باید حتما با مقدار آن در بخش فلاتر برابر باشد.
کدهای بخش دارت
نحوه مقدار دهی کردن Platform Channel در قسمت کدهای دارت:
static const platform = MethodChannel('com.example.services_demo/service');
این مقدار باید با CHANNEL یکسان باشد.
در بخش initState کدهای زیر را قرار دهید تا سرویس شروع شود.
@override
void initState() {
super.initState();
connectToService();
}
همچنین در متد connectToService کدهای زیر را بنویسید که متد connect صدا زده می شود.
Future<void> connectToService() async {
try {
await platform.invokeMethod<void>('connect');
print('Connected to service');
} on Exception catch (e) {
print(e.toString());
}
}
خب بعد از اینکه با موفقیت سرویس خودمون و ایجاد کردیم حالا میتونیم اطلاعات را دریافت کنیم.
Future<String> getDataFromService() async {
try {
final result = await platform.invokeMethod<String>('start');
return result;
} on PlatformException catch (e) {
print(e.toString());
}
return 'No Data From Service';
}
مطالب زیر را حتما مطالعه کنید
آموزش پیاده سازی لینت Lint در برنامه نویسی فلاتر
آموزش الگوی تزریق وابستگی در فلاتر Dependency Injection
کتاب های آموزش برنامه نویسی فلاتر + دانلود PDF
آموزش نصب فلاتر و رفع خطاهای رایج ساخت پروژه + ویدیو
آموزش استفاده از نقشه در فلاتر
آموزش ساخت Navigation Drawer در فلاتر
7 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
عکس اول مربوط به پروژه جاواست نه فلاتر.
عکس ساخت سرویس داخل اندروید استودیو هست ارتباطی به زبان و فریمورک نداره.
میشه بگید چرا داخل کلاس MyThread حلقه for گذاشتید که فقط یه بار اجرا میشه. try catch رو بدون اون هم می تونستید بنویسید.
سلام این حلقه مثال هست برای اینکه نشون بده میتونید عملیات های مختلف و انجام بدید.
سلام خسته نباشید .
عکس اول رو کجای پروژه فلاتر باید ایجاد کنم ؟
فایل اندروید رو داخل اندروید استودیو باز میکنم اما فولدر ها متفاوتن .
ممنون از شما
سلام داخل پکیج اصلی که فایل کلاس های برنامه قرار دارند میتونید سرویس جدید ایجاد کنید.
سلام این برنامه نویسی بک اند با دارت هس؟