شرح AsyncTask في الاندرويد

البرنامج التعليمي AsyncTask مع مثال Android Studio [خطوة بخطوة]

في Android ، يسمح لنا AsyncTask (مهمة غير متزامنة ) بتشغيل التعليمات في الخلفية ثم المزامنة مرة أخرى مع مؤشر ترابطنا الرئيسي. ستتجاوز هذه الفئة طريقة واحدة على الأقل ، مثل doInBackground (Params) وغالبًا ما تتجاوز الطريقة الثانية onPostExecute (النتيجة).

يتم استخدام فئة AsyncTask للقيام بعمليات في الخلفية من شأنها تحديث واجهة المستخدم (واجهة المستخدم). استخدمناه بشكل أساسي للعمليات القصيرة التي لن تؤثر على مؤشر ترابطنا الرئيسي.

يتم تنفيذ فئة AsyncTask أولاً باستخدام طريقة execute (). في الخطوة الأولى ، يتم استدعاء AsyncTask onPreExecute () ثم onPreExecute () استدعاءات doInBackground () للعمليات الخلفية ثم استدعاءات doInBackground () onPostExecute () لتحديث واجهة المستخدم.

مثال AsyncTask Android Flow


الحاجة إلى 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

يمكنك أدناه تنزيل الكود ، والاطلاع على الإخراج النهائي واتباع الشرح خطوة بخطوة للمثال:

كود التحميل

مثال AysncTask في Android Studio

الخطوة 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>