تعريف سرويس اندرويد ( این صفحه 4021 مرتبه بازدید شده است )
تعريف سرويس اندرويد:
ابتدا بايد تعريف سرويس در مانيفست انجام شود
<service
android:name="MyService"
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>
|
سرويس با حداقل كد به اين صورت خواهد بود كه شامل معرفي سرويس، شروع و توقف سرويس مي باشد.
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
|
فايل جداگانه سرويس اينگونه است :
package com.ebrahimi.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
|
كار ساخت سرويس مقدماتي تمام است
فراخواني سرويس :
يك سرويس را () مي توانند فراخواني كنند. كد فراخواني اينگونه است :
Intent i= new Intent(context, MyService.class);
// potentially add data to the intent
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
|
البته براي ارتباط با سرويس مي توانيد از متد bindService()
نيز استفاده كنيد
زماني كه يك سرويس با متد startService(intent)
فراخواني مي شود اگر شي سرويس قبلا ايجاد نشده باشد، شي ايجاد شده و سپس متد onCreate()
نيز اجرا مي شود
زماني كه سرويس شروع بكار كند متد onStartCommand(intent)
نيز اجرا خواهد شد. شي دريافت شده از متد startService(intent)
نيز به آن ارجاع داده مي شود
اگر سرويس قبلا اجرا شده باشد با فراخواني متد startService(intent)
، متد onStartCommand()
فراخواني و اجرا مي شود. پس برنامه بايد اين قابليت را داشته باشد كه چندين بار فراخواني و اجرا شود.
سوال : آيا مي توان سرويس را دو بار و همزمان اجرا كرد؟ خير چون اين برنامه توسط ترد كاربران وAndroid system اجرا مي شود هيچگاه همزمان توسط چند درخواست اجرا نمي شود. همچنين سرويس هيچگاه دوبار اجرا نخواهد شد.
رفتار راه اندازي مجدد سرويس :
با اجراي متد onStartCommand()
مقدار عددي (int) برگشت داده مي شود تا در صورتيكه سرويس توسط پلتفرم اندرويد كشته شد رفتار اجراي مجدد آن را تعيين مي كند. مهمترين ثابتهائي كه براي اينكار استفاده مي شوند به شرح جدول زير مي باشد:
عنوان كليد
|
شرح عملكرد
|
Service.START_STICKY
|
اين سرويس در صورت كشته شدن بصورت خودكار اجرا خواهد شد. ورودي تابع onStartCommand مقدار null خواهد بود. اين كليد براي سرويسهائي استفاده مي شوند كه مستقل بوده و به مقدار ورودي از intent وابستگي ندارند
|
Service.START_NOT_STICKY
|
اين سرويس بصورت خودكار اجرا نخواهد شد و مناسب سرويسهائي است كه بصورت دوره اي اجرا مي شود. اين سرويس زماني مجددا اجرا خواهد شد كه متد startService() مجددا فراخواني شود
|
Service.START_REDELIVER_INTENT
|
اين سرويس مشابه كليد ثابت Service.START_STICKY خواهد بود با اين تفاوت كه شي پاس داده شده توسط Intent بصورت كامل به متد onStartCommand پاس داده خواهد شد
|
نكته : نوع شروع سرويس را مي توان با استفاده از تابع Intent.getFlags()
تشخيص داد. كليد START_FLAG_REDELIVERY
براي سرويسي كه به روش Service.START_REDELIVER_INTENT اجرا شده است و كليد START_FLAG_RETRY
براي سرويسي كه به روش Service.START_STICKY اجرا شده است.
توقف سرويس :
براي توقف سرويس متد stopService()
فراخواني مي شود. سرويس هر چند بار كه اجرا شده باشد با يكبار فراخواني متد فوق متوقف خواهد شد.
سرويس مي تواند خودش را توسط متد stopSelf()
متوقف كند. معمولا اين توقف زماني اجرا مي شود كه كار سرويس خاتمه يافته باشد
الصاق به سرويس
الصاق از يك اكتيويتي :
اگر فعاليتي بخواهد با سرويس ارتباط برقرار كند بايد توسط متد bindService()
به آن الصاق شود تا سرويس شروع شود.
اين متد به شي ServiceConnection
بعنوان پارامتر ورودي براي شروع الصاق و براي خاتمه دادن به الصاق توسط متد onBind()
نياز دارد. اين متد شي IBinder
به ServiceConnection
برميگرداند.
اكتيويتي مي تواند از شي IBinder
براي ارتباط با سرويس استفاده كند
وقتيكه متد الصاق كارش را خاتمه داد، متد onStartCommand()
در سرويس اجرا شده و شي Intent
كه در متد bindService()
استفاده شده بود به آن پاس داده مي شود.
اجراي سرويس محلي :
اگر سرويس بر روي ترد اكتيويتي اجرا شود مي توان به راحتي به آن دسترسي داشت
اجراي سرويس مستقل :
براي دسترسي به سرويسي كه ترد مستقل دارد به ارتباط بين روالها IPC (Interprocess Communication) براي ارتباط با آن نياز خواهد بود
اجراي سرويس در ترد مستقل :
براي آنكه سرويس بر روي ترد مستقل اجرا شود بايد در مانيفست عبارت android:process=":process_description"
را ذكر كنيد
<service
android:name="WordService"
android:process=":my_process"
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>
|
به نحوه نوشتن علامت :
جلوي نام مورد نظردقت كنيد. همين علامت به اندرويد اعلام مي كند كه سرويس بايد برروي ترد مستقل خود اجرا شود. اگر علامت كلون (:
) قرار داده نشود ترد استفاده شده ترد عمومي بوده و توسط ساير برنامه ها نيز استفاده خواهد شد.
اجراي سرويس بر روي ترد خودش سبب خواهد شد تا در صورت انجام كار سنگين، جلوي روال عادي برنامه گرفته نشده و برنامه "هنگ" نكند. از سوئي چون برنامه بر روي ترد خودش كار مي كند براي ارتباط با آن نياز به IPC خواهد بود.
حتي در حالتي كه سرويس بر روي ترد خودش كار مي كند لازم است تا از اجراي غيرهمزمان (asynchronous) استفاده نمود تا بتوان به شبكه (network) دسترسي داشت زيرا اندرويد اجازه دسترسي به شبكه از طريق ترد اصلي يك پروسه را نخواهد داد.
كجا براي سرويس از ترد جداگانه استفادا كنيم :
اجراي سرويس بر روي ترد جداگانه به آن سرويس فضاي آدرس حافظه جدا گانه داده و عمليات پاكسازي (garbage collector) ماشين مجازي در آن اثري بر روي پروسه اصلي نخواهد داشت.
كمتر نياز است تا سرويس را بر روي ترد مستقل اجرا نمود. اين روش ارتباط يافتن با سرويس را مشكل تر و استفاده از سرويس را سختتر خواهد نمود
تذكر : اگر قرار باشد تا سرويس در اخيترا ساير برنامه نيز باشد بايد آنرا بر روي ترد مستقل اجرا نمود
راههاي ارتباط با سرويس :
فراخواني با Intent:
روش كار آسان است. سرويس با Intent فراخواني مي شود. سرويس اطلاعات خود را از Intent دريافت مي كند و كارش را انجام مي دهد نياز به خبررساني (notificatiuon) نيز نمي باشد. مثلا سرويس كه محتوائي را به روز مي كند. پس محتوا را دريافت نموده و آنرا به روزرساني مي كند.
فراخواني با استفاده از گيرنده ها (receiver) :
در اين روش از رويدادهاي انتشار و گيرنده هاي ثبت نام شده استفاده مي شود. مثلا اكتيويتي شما اقدام به ثبت نام يك گيرنده انتشاراتي نموده و سرويس مورد نظر نيز رويدادهاي مورد درخواست را براي آن فعاليت ارسال مي كند. در اين روش سرويس خاتمه درخواست را به درخواست ثبت نام شده اعلام خواهد نمود. اين روش براي سرويس هاي محلي و آنها كه در پروسه خودشان كار مي كنند مفيد است.
تذكر : كتابخانه نسخه 4 اندرويد كلاس LocalBroadcastManager
را در اختيار برنامه نويسان قرار داده است. اين كلاس كمكي براي ثبت درخواست و انتشار اطلاعات به اشياء محلي درون برنامه شما بوده كه امنيت و سرعت را بهبود مي دهد زيرا رويدادهاي انتشار تنها درون پروسه كاري شما قابل مشاهده بوده و ديگر نياز به استفاده از رويدادهاي استاندارد نمي باشد
الصاق اكتيويتي به سرويس محلي :
اگر سرويس در تردي اجرا شده باشد كه اكتيويتي نيز در آن ترد اجرا شده است، اكتيويتي مي تواند مستقيما به آن الصاق شود. اين روش نسبتا آسان و كارآمد بوده و براي فعاليتهائي كه نياز به لايه ارتباط سريع با سرويس دارند پيشنهاد مي شود
دستگيره و گيرنده نتيجه يا گيرنده پيام :
اگر لازم باشد كه سرويس به اكتيويتي نتيجه بدهد مي تواند با استفادده از شي Messenger
و از طريق متغييرهاي داده در Intent اطلاعات دريافت نموده و اگر Messenger
به Handler
الصاق شده باشد سرويس خواهد توانست تا شي از نوع Message
را به فعاليت بازگرداند
شي Messenger
همچنين متدي به نام getBinder()
دارد كه اجازه بازگردانيدن شي Messenger
به اكتيويتي را مي دهد
اين روش براي سرويسهاي محلي كه بر روي ترد مستقل عمل مي كنند مفيد است
توليد فايل AIDL براي ارتباط با ديگر سرويس ها :
اگر بخواهيد با سرويسي كه بر روي پروسه ديگري در حال كار مي باشد ارتباط پيدا كنيد بايد از IPC بعنوان راه ارسال ديتا استفاده كنيد. براي اينكار لازم است تا فايل AIDL ايجاد كنيد كه چيزي شبيه رابط جاوا مي باشد با اين تفاوت كه پسوند فايل .aidl مي باشد
سرويسهاي نمونه :
شروع سرويس بصورت مرتب با استفاده از مديريت آلارم :
براي اطمينان از كار كردن مداوم يك سرويس سرويس نيز مانند هر اكتيويتي ديگري ممكن است توسط اندرويد متوقف شود. به اين دليل نمي توان از تايمر براي بررسي اجراي قطعي سرويس استفاده صحيحي نمود.
براي برنامه ريزي دقيق سرويس بهتر است تا از كلاس AlarmManager
استفاده نمود. نمونه كد زير روش اجراي كار را نمايش مي دهد:
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent);
|
استفاده از IntentServiceبراي سرويس هاي يكبار مصرف :
از اين سرويس براي اجراي يكباره يك فعاليت در پس زمينه استفاده مي شود كه در خاتمه نيز بصورت خودكار متوقف مي شود. اين سرويس داراي متد onHandleIntent() كه بصورت غيرهم زمان توسط اندرويد اجرا مي شود.
مثال استفاده از سرويس پس زمينه براي دانلود فايل از اينترنت :
در اين مثال از سرويس IntentService براي يكبار دريافت فايل از سرور استفاده نموده و در خاتمه كار نيز به كاربر خبر خاتمه دانلود را اعلام خواهيم نمود
محتواي فايل سرويس به اين شرح است :
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
public class DownloadService extends IntentService {
private int result = Activity.RESULT_CANCELED;
public static final String URL = "urlpath";
public static final String FILENAME = "filename";
public static final String FILEPATH = "filepath";
public static final String RESULT = "result";
public static final String NOTIFICATION = "com.vogella.android.service.receiver";
public DownloadService() {
super("DownloadService");
}
// will be called asynchronously by Android
@Override
protected void onHandleIntent(Intent intent) {
String urlPath = intent.getStringExtra(URL);
String fileName = intent.getStringExtra(FILENAME);
File output = new File(Environment.getExternalStorageDirectory(),
fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// successfully finished
result = Activity.RESULT_OK;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
publishResults(output.getAbsolutePath(), result);
}
private void publishResults(String outputPath, int result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(FILEPATH, outputPath);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}
|
فايل مانيفست را نيز تغيير دهيد تا اجازه نوشتن در حافظه جانبي را داشته باشيد و همچنين سرويس را معرفي كنيد :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vogella.android.service.receiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.vogella.android.service.receiver.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.vogella.android.service.receiver.DownloadService" >
</service>
</application>
</manifest>
|
حالا فايل لي اوت را نيز به اين صورت تغيير دهيد :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Download" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status: " />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Not started" />
</LinearLayout>
</LinearLayout>
|
براي اجراي دستورات لازم در فايل MainActivity
نيز بايد تغييراتي بدهيد :
package com.vogella.android.service.receiver;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView textView;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
String string = bundle.getString(DownloadService.FILEPATH);
int resultCode = bundle.getInt(DownloadService.RESULT);
if (resultCode == RESULT_OK) {
Toast.makeText(MainActivity.this,
"Download complete. Download URI: " + string,
Toast.LENGTH_LONG).show();
textView.setText("Download done");
} else {
Toast.makeText(MainActivity.this, "Download failed",
Toast.LENGTH_LONG).show();
textView.setText("Download failed");
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.status);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(DownloadService.NOTIFICATION));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
public void onClick(View view) {
Intent intent = new Intent(this, DownloadService.class);
// add infos for the service which file to download and where to store
intent.putExtra(DownloadService.FILENAME, "index.html");
intent.putExtra(DownloadService.URL,
"http://www.vogella.com/index.html");
startService(intent);
textView.setText("Service started");
}
}
|
پس از اجراي برنامه با فشردن كليد فايل دريافت خواهد شد. با پايان كار نيز فرم بازسازي شده و يك پيام اتمام كار رابه كاربر خبر مي دهد.
مي توانيد سرويس را به گونه اي تغيير دهيد كه سرويس بر روي ترد خودش كار كند.
تعريف و استفاده از سرويس ها ي محلي :
اين نمونه كد سرويس محلي را تعريف نموده و از آن استفاده ميكند :
فايل سرويس را تعريف كنيد
package de.vogella.android.ownservice.local;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class LocalWordService extends Service {
private final IBinder mBinder = new MyBinder();
private ArrayList<String> list = new ArrayList<String>();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Random random = new Random();
if (random.nextBoolean()) {
list.add("Linux");
}
if (random.nextBoolean()) {
list.add("Android");
}
if (random.nextBoolean()) {
list.add("iPhone");
}
if (random.nextBoolean()) {
list.add("Windows7");
}
if (list.size() >= 20) {
list.remove(0);
}
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
LocalWordService getService() {
return LocalWordService.this;
}
}
public List<String> getWordList() {
return list;
}
}
|
حالا فايل جديد براي دو كلاس زير تعريف كنيد كه كار گيرنده ها را (BroadcastReceivers
) انجام مي دهند :
package de.vogella.android.ownservice.local;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyScheduleReceiver extends BroadcastReceiver {
// restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 30;
@Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// start 30 seconds after boot completed
cal.add(Calendar.SECOND, 30);
// fetch every 30 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
// service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
// REPEAT_TIME, pending);
}
}
|
package de.vogella.android.ownservice.local;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyStartServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, LocalWordService.class);
context.startService(service);
}
}
|
فايل مانيفست را به اين صورت تعريف كنيد:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.vogella.android.ownservice.local"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".LocalWordService"
android:icon="@drawable/icon"
android:label="@string/service_name" >
</service>
<receiver android:name="MyScheduleReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name="MyStartServiceReceiver" >
</receiver>
</application>
</manifest>
|
فايل لي اوت را اينگونه تعريف كنيد :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Update" >
</Button>
<ListView
android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
|
حالا فايل اصلي اكتيويتي را تعريف كنيد :
package de.vogella.android.ownservice.local;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class MainActivity extends ListActivity {
private LocalWordService s;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wordList = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
wordList);
setListAdapter(adapter);
}
@Override
protected void onResume() {
super.onResume();
Intent intent= new Intent(this, LocalWordService.class);
bindService(intent, mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
unbindService(mConnection);
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder binder) {
LocalWordService.MyBinder b = (LocalWordService.MyBinder) binder;
s = b.getService();
Toast.makeText(MainActivity.this, "Connected", Toast.LENGTH_SHORT)
.show();
}
public void onServiceDisconnected(ComponentName className) {
s = null;
}
};
private ArrayAdapter<String> adapter;
private List<String> wordList;
public void onClick(View view) {
if (s != null) {
Toast.makeText(this, "Number of elements" + s.getWordList().size(),
Toast.LENGTH_SHORT).show();
wordList.clear();
wordList.addAll(s.getWordList());
adapter.notifyDataSetChanged();
}
}
}
|
برنامه را اجرا كنيد. اگر كليد را لمس كنيد اطلاعات به سرويس ارسال مي شود و جواب آن به برنامه برگشته و در ليست اضافه خواهد شد تا ملاحظه كنيد