البرنامج التعليمي AsyncTask مع مثال Android Studio [خطوة بخطوة]
في Android ، يسمح لنا AsyncTask (مهمة غير متزامنة ) بتشغيل التعليمات في الخلفية ثم المزامنة مرة أخرى مع مؤشر ترابطنا الرئيسي. ستتجاوز هذه الفئة طريقة واحدة على الأقل ، مثل doInBackground (Params) وغالبًا ما تتجاوز الطريقة الثانية onPostExecute (النتيجة).
يتم استخدام فئة AsyncTask للقيام بعمليات في الخلفية من شأنها تحديث واجهة المستخدم (واجهة المستخدم). استخدمناه بشكل أساسي للعمليات القصيرة التي لن تؤثر على مؤشر ترابطنا الرئيسي.
يتم تنفيذ فئة AsyncTask أولاً باستخدام طريقة execute (). في الخطوة الأولى ، يتم استدعاء AsyncTask onPreExecute () ثم onPreExecute () استدعاءات doInBackground () للعمليات الخلفية ثم استدعاءات doInBackground () onPostExecute () لتحديث واجهة المستخدم.
جدول المحتويات
الحاجة إلى AsyncTask في Android
بشكل افتراضي ، يعمل كود التطبيق الخاص بنا في مؤشر ترابطنا الرئيسي وبالتالي يتم تنفيذ كل عبارة في تسلسل. إذا احتجنا إلى أداء مهام / عمليات طويلة ، فسيتم حظر مؤشر ترابطنا الرئيسي حتى تنتهي العملية المقابلة. لتوفير تجربة مستخدم جيدة في تطبيقنا ، نحتاج إلى استخدام فئة AsyncTasks التي تعمل في سلسلة منفصلة. ستنفذ هذه الفئة كل شيء في طريقة doInBackground () داخل خيط آخر لا يمكنه الوصول إلى واجهة المستخدم الرسومية حيث توجد جميع العروض. تقوم طريقة onPostExecute () لهذه الفئة بمزامنة نفسها مرة أخرى مع مؤشر ترابط واجهة المستخدم الرئيسي وتسمح لها بإجراء بعض التحديث. يتم استدعاء هذه الطريقة تلقائيًا بعد انتهاء طريقة doInBackground من عملها.
بناء جملة AsyncTask في Android
لاستخدام AsyncTask ، يجب أن تقوم بتصنيفه إلى فئة فرعية. المعلمات هي AsyncTask التالية <TypeOfVarArgParams ، ProgressValue ، ResultValue>. هنا هو
بناء جملة فئة AsyncTask:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls) { // code that will run in the background return ; } protected void onProgressUpdate(Integer... progress) { // receive progress updates from doInBackground } protected void onPostExecute(Long result) { // update the UI after background processes completes } }
عمليات تنفيذ فئة AsyncTask من الخيط الرئيسي:
فيما يلي بناء الجملة لتنفيذ فئات AsyncTasks.
new DownloadFilesTask().execute(url1, url2, url3);
الأنواع العامة لـ AsyncTask في Android
الأنواع الثلاثة التي تستخدمها المهمة غير المتزامنة هي كالتالي:
AsyncTask <TypeOfVarArgParams ، ProgressValue ، ResultValue>
1. TypeOfVarArgParams:
Params هو نوع المعلمات التي يتم إرسالها إلى المهمة عند التنفيذ.
2. قيمة التقدم ProgressValue : التقدم هو نوع وحدات التقدم المنشورة أثناء حساب الخلفية.
3. ResultValue: ResultValue هو نوع نتيجة حساب الخلفية.
طريقة AsyncTask في Android
في Android ، يتم تنفيذ AsyncTask ويمر بأربع خطوات أو طريقة مختلفة. فيما يلي هذه الطرق الأربعة لـ AsyncTasks.
1. onPreExecute () - يتم استدعاؤه في مؤشر ترابط واجهة المستخدم الرئيسي قبل تنفيذ المهمة. تُستخدم هذه الطريقة بشكل أساسي لإعداد المهمة على سبيل المثال من خلال إظهار شريط التقدم أو ProgressDialog في واجهة المستخدم (واجهة المستخدم).
2. doInBackground (Params) - يتم استدعاء هذه الطريقة على مؤشر ترابط الخلفية فور انتهاء onPreExecute () من تنفيذه. الغرض الرئيسي من هذه الطريقة هو إجراء عمليات الخلفية التي يمكن أن تستغرق وقتًا طويلاً. يتم تمرير معلمات المهمة غير المتزامنة إلى هذه الخطوة للتنفيذ. يجب إرجاع نتيجة العمليات بهذه الخطوة وستتم إعادتها إلى الخطوة / الطريقة الأخيرة ، أي onPostExecutes (). يمكن أن تستخدم هذه الطريقة أيضًا publishProgress (Progress…) لنشر وحدة أو أكثر من وحدات التقدم. سيتم نشر هذه القيم في مؤشر ترابط واجهة المستخدم الرئيسي في أسلوب onProgressUpdate (التقدم ...).
3. onProgressUpdate (Progress ...) - يتم استدعاء هذه الطريقة في مؤشر ترابط واجهة المستخدم الرئيسي بعد استدعاء publishProgress (Progress…). توقيت التنفيذ غير محدد. تُستخدم هذه الطريقة لعرض أي شكل من أشكال التقدم في واجهة المستخدم أثناء تنفيذ عمليات الخلفية. يمكننا أيضًا تحديث حالة تقدمنا للحصول على تجربة مستخدم جيدة.
4. onPostExecute (Result) - يتم استدعاء هذه الطريقة في مؤشر ترابط واجهة المستخدم الرئيسية بعد انتهاء عملية الخلفية في أسلوب doInBackground. يتم تمرير نتيجة عملية الخلفية إلى هذه الخطوة كمعامل ومن ثم يمكننا بسهولة تحديث واجهة المستخدم الخاصة بنا لإظهار النتائج.
قواعد AsyncTask
هناك بعض قواعد الترابط التي يجب اتباعها حتى يعمل هذا الفصل بشكل صحيح:
1. يجب تحميل هذه الفئة في مؤشر ترابط واجهة المستخدم. يتم ذلك تلقائيًا اعتبارًا من JELLY_BEAN.
2. يجب إنشاء مثيل المهمة في مؤشر ترابط واجهة المستخدم.
3. تنفيذ طريقة (Params…) التي تنفذه ، يجب أن يتم استدعاؤها في مؤشر ترابط واجهة المستخدم.
4. لا تستدعي onPreExecute () ، onPostExecute (نتيجة) ، doInBackground (Params ...) ، onProgressUpdate (التقدم ...) يدويًا ، فقط ينفذ الفصل ثم سوف يستدعي تلقائيًا للحصول على تجربة مستخدم جيدة.
مثال AsyncTask في Android Studio
في هذا المثال خطوة بخطوة ، نستخدم فئة AsyncTask لإجراء عمليات الشبكة. هنا أولاً سنقوم بجلب بعض البيانات من API (خدمة الويب) وعرضها في واجهة المستخدم الخاصة بنا. لذلك ، نقوم أولاً بإنشاء زر وعند النقر عليه نقوم بتنفيذ فئة AsyncTasks التي تجلب البيانات في الخلفية وبعد الحصول على استجابة من API في طريقة postExecute () ، نعرض نفس البيانات في واجهة المستخدم الخاصة بنا.
عنوان url الخاص بواجهة برمجة التطبيقات لدينا: http://mobileappdatabase.in/demo/smartnews/app_dashboard/jsonUrl/single-article.php؟article-id=71
يمكنك أدناه تنزيل الكود ، والاطلاع على الإخراج النهائي واتباع الشرح خطوة بخطوة للمثال:
الخطوة 1: قم بإنشاء مشروع جديد وقم بتسميته AsyncTasksExample.
الخطوة 2: افتح build.gradle وأضف تبعية مكتبة Picasso .
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.abhiandroid.asynctasksexample" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.squareup.picasso:picasso:2.5.2' testCompile 'junit:junit:4.12' }
Step 3: أفتح res -> layout ->activity_main.xml (او) main.xml وأضف الكود التالي :
In this step firstly we create Button to perform click event and TextView‘s and ImageView to display the fetched API data.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="30dp" tools:context="com.abhiandroid.asynctasksexample.MainActivity"> <Button android:id="@+id/displayData" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="20dp" android:background="@color/colorPrimary" android:text="Display Data" android:textColor="#fff" android:textSize="20sp" /> <TextView android:id="@+id/titleTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:text="Title: " android:textColor="#000" android:textSize="18sp" /> <TextView android:id="@+id/categoryTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="Category: " android:textColor="#000" android:textSize="18sp" /> <ImageView android:id="@+id/imageView" android:scaleType="centerCrop" android:layout_width="match_parent" android:layout_height="200dp" android:layout_gravity="center" android:layout_marginTop="20dp" /> </LinearLayout>
Step 4: أفتح src -> package -> MainActivity.java
في هذه الخطوة ، نحصل أولاً على مرجع Button و TextView و ImageView . بعد ذلك نقوم بتنفيذ حدث setOnClickListener على الزر وتنفيذ فئة AsyncTasks. في فئة AsyncTasks ، نعرض أولاً مربع حوار التقدم في طريقة onPreExecute ، ثم ننفذ واجهة برمجة التطبيقات في طريقة doInBackground وبعد الحصول على استجابة في طريقة postExecute ، نقوم ببساطة بتحليل بيانات JSON وعرض العنوان والفئة والصورة في واجهة المستخدم. في هذا ، استخدمنا أيضًا مكتبة Picasso لجلب الصورة من URL.
package com.abhiandroid.asynctasksexample; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.squareup.picasso.Picasso; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MainActivity extends AppCompatActivity { String apiUrl = "http://mobileappdatabase.in/demo/smartnews/app_dashboard/jsonUrl/single-article.php?article-id=71"; String title, image, category; TextView titleTextView, categoryTextView; ProgressDialog progressDialog; Button displayData; ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // get the reference of View's titleTextView = (TextView) findViewById(R.id.titleTextView); categoryTextView = (TextView) findViewById(R.id.categoryTextView); displayData = (Button) findViewById(R.id.displayData); imageView = (ImageView) findViewById(R.id.imageView); // implement setOnClickListener event on displayData button displayData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // create object of MyAsyncTasks class and execute it MyAsyncTasks myAsyncTasks = new MyAsyncTasks(); myAsyncTasks.execute(); } }); } public class MyAsyncTasks extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); // display a progress dialog for good user experiance progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setMessage("Please Wait"); progressDialog.setCancelable(false); progressDialog.show(); } @Override protected String doInBackground(String... params) { // implement API in background and store the response in current variable String current = ""; try { URL url; HttpURLConnection urlConnection = null; try { url = new URL(apiUrl); urlConnection = (HttpURLConnection) url .openConnection(); InputStream in = urlConnection.getInputStream(); InputStreamReader isw = new InputStreamReader(in); int data = isw.read(); while (data != -1) { current += (char) data; data = isw.read(); System.out.print(current); } // return the data to onPostExecute method return current; } catch (Exception e) { e.printStackTrace(); } finally { if (urlConnection != null) { urlConnection.disconnect(); } } } catch (Exception e) { e.printStackTrace(); return "Exception: " + e.getMessage(); } return current; } @Override protected void onPostExecute(String s) { Log.d("data", s.toString()); // dismiss the progress dialog after receiving data from API progressDialog.dismiss(); try { // JSON Parsing of data JSONArray jsonArray = new JSONArray(s); JSONObject oneObject = jsonArray.getJSONObject(0); // Pulling items from the array title = oneObject.getString("title"); category = oneObject.getString("category"); image = oneObject.getString("image"); // display the data in UI titleTextView.setText("Title: "+title); categoryTextView.setText("Category: "+category); // Picasso library to display the image from URL Picasso.with(getApplicationContext()) .load(image) .into(imageView); } catch (JSONException e) { e.printStackTrace(); } } } }
الخطوة 5: افتح AndroidManifest. xml وأضف إذن الإنترنت Internet Permission.
<uses-permission android:name="android.permission.INTERNET"/>
في هذه الخطوة نحدد إذن الإنترنت.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.abhiandroid.asynctasksexample"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>