اجرای متعدد یک سری کد در Activity های مختلف، بدون احتیاج به دوباره نوشتن آنها، با ساخت یک کلاس (Class) جدید، در برنامه نویسی اندروید
حتما تاکنون برایتان پیش آمده است که یک سری کد را باید چندین بار در Activity های مختلف می نوشته اید و بنابراین علاوه بر زیاد شدن حجم کدهای برنامه اندروید، با این مشکل نیز مواجه بوده اید که برای تغییر آن کدها، باید کدهای Activity های مختلف را تغییر می داده اید. اما این مشکل، یک راه حل دارد و آن این است که یک کلاس (class) جدید برای برنامه اندروید تعریف کنید و کدهای مورد نظر خود را در آن قرار بدهید، سپس هر زمان که لازم باشد، در Activity دلخواه، یک شیء (object) از آن کلاس (class) می سازید و کدهای مربوط به آن را اجرا می کنید. چگونگی این عملیات را در ادامه با مثال هایی شرح خواهیم داد.
مفاهیم مربوط به کار با کلاس ها (class) گسترده است و ممکن است یک عملیات دلخواه را بتوانیم با چندین روش انجام بدهیم، اما ما قصد نداریم این مبحث بیش از حد طولانی شود و بنابراین برای هر حالت، یک کد را بیان می کنیم که ما را به هدفمان می رساند، اما در سایر مباحث سایت کلیدستان سعی می کنیم که مفاهیم به صورت وسیعتری شرح داده شوند و انواع روش های اجرای عملیات ها نیز بیان شوند.
قبل از اینکه در مورد ساخت کلاس (class) صحبت کنیم، بهتر است که حالت هایی که معمولا پیش می آید را شرح بدهیم :
از نظر دریافت ورودی توسط کلاس (class)، دو حالت داریم :
1- کلاس (class) مورد نظر، نیازی به دریافت ورودی ندارد.
2- کلاس (class) مورد نظر، نیاز به دریافت ورودی دارد.
از نظر برگرداندن خروجی توسط کلاس (class)، دو حالت داریم (یعنی کلاس به Activity مورد نظر، مقدار یا مقدارهایی را برگرداند یا خیر) :
1- کلاس (class) مورد نظر، هچیچ خروجی را برنمی گرداند.
2- کلاس (class) مورد نظر، یک یا چند خروجی را برمی گرداند.
همان طور که گفتیم، در Activity های مختلف، از آن کلاس (class)، شئ (object) می سازیم، بنابراین بر اساس شناسایی Activity بر اساس Context مربوط به Activity ، دو حالت زیر را داریم :
1- کدهایی که می خواهیم در کلاس (class) بنویسیم به گونه ای است که نیاز به شناسایی Activity بر اساس Context مربوط به Activity دارد (بنابراین باید Context مربوط به Activity را به عنوان ورودی به آن کلاس بفرستیم).
2- کدهایی که می خواهیم در کلاس (class) بنویسیم به گونه ای است که نیاز به شناسایی Activity بر اساس Context مربوط به Activity ندارد.
ساخت یک کلاس (class) جدید، در پروژه اندروید :
ابتدا چگونگی ساخت یک کلاس (class) جدید را شرح می دهیم (بعدا با تغییر دادن کدهای کلاس، می توانیم حالت های مختلف مورد نظرمان را برای آن ایجاد کنیم). فرض کنید در برنامه eclipse ، یک پروژه اندروید داریم که تنها دارای یک Activity با نام MainActivity.java می باشد :

اکنون می خواهیم یک کلاس (class) جدید با نام MyClass در پروژه اندروید بسازیم. برای این منظور، بر روی نام پروژه اندروید (یا نام package آن)، با موس، کلیک سمت راست نموده و ابتدا گزینه New و سپس گزینه Class را انتخاب می کنیم :

پنجره ای به شکل زیر نمایش داده می شود :

در قسمت Package ، باید package ای که می خواهیم کلاس (class) جدید در آن قرار بگیرد را انتخاب کنیم. برای این منظور، بر روی دکمه Browse در جلوی آن کلیک می کنیم و package پروژه اندروید را انتخاب می کنیم (یا اگر package های دیگری در پروژه اندروید دارید، می توانید یکی از آنها را انتخاب کنید ( آموزش شماره 2670 )) :

پس از انتخاب نام package ، بر روی دکمه OK کلیک می کنیم.
در قسمت Name ، باید نام مورد نظرمان برای کلاس (Class) را بنویسیم (مثلا من نام MyClass را انتخاب می کنم).
در قسمت Superclass ، باید یک کلاس را به عنوان Superclass انتخاب کنید. برای تغییر موردی که از قبل برای آن تعیین شده است، بر روی دکمه Browse کلیک می کنیم تا پنجره ای به شکل زیر نمایش داده شود :

در قسمت Choose a type ، کلمه test را می نویسیم تا موردی با عنوان TestCase - junit.framework نمایش داده شود :

همین مورد را انتخاب کرده و بر روی دکمه OK کلیک می کنیم. بنابراین گزینه های انتخاب شده در پنجره، به صورت زیر می باشد :

بر روی دکمه Finish کلیک می کنیم تا کلاس (class) جدید ساخته شود (فایل مربوط به آن نیز باز شده و کدهایش نمایش داده می شود) :

بنابراین کدهای کلاس MyClass به صورت زیر می باشد :
import junit.framework.TestCase;
public class MyClass extends TestCase {
}
اگرچه موارد مربوط به کلاس را در محیطی گرافیکی تعیین کردیم، ولی اکنون با ویرایش کدهای فایل MyClass.jaa نیز می توانیم آنها را تغییر بدهیم. به عنوان مثال، superclass را می توانیم با تغییر دو خط زیر از کدها، تغییر بدهیم :
public class MyClass extends TestCase {
ابتدا باید عبارت junit.framework.TestCase تغییر داده شده و سپس TestCase نیز باید تغییر یابد (یعنی نام کلاسی که بر اساس توسعه (extend) آن در حال ساخت این کلاس جدید هستیم).
خوب اکنون قصد داریم کدهایی که باید چندین بار در برنامه اندروید اجرا شوند را در کلاس MyClass بنویسیم. برای کدنویسی، دو حالت کلاس با ورودی و کلاس بدون ورودی را شرح خواهیم داد.
نوشتن کدهای کلاس (class)، در حالتی که کلاس به ورودی نیاز ندارد :
در این حالت، چون کدهای مورد نظرمان، نیاز به دریافت اطلاعات از Activity ندارند، بنابراین کلاس هیچ ورودی نخواهد داشت. به عنوان مثال، فرض کنید بخواهیم کدهای محاسباتی زیر را در کلاس بنویسیم :
public int number2 = 30;
public int number3 = number1*number2;
محاسبه بالا، تنها ضرب دو عدد در یکدیگر و به دست آوردن نتیجه می باشد (یک محاسبه بسیار ساده).
بنابراین کدهای کلاس MyClass به صورت زیر خواهد بود :
import junit.framework.TestCase;
public class MyClass extends TestCase {
public int number1 = 20;
public int number2 = 30;
public int number3 = number1*number2;
}
اکنون برای اینکه این کدها در Activity مورد نظرمان اجرا شوند، باید کد زیر را در میان کدهای Activity بنویسیم :
با کد فوق، از کلاس MyClass ، یک شیء (object) با نام myClass ساخته ایم. با توجه به ساختار کدهای کلاس MyClass ، به محض ساخته شدن شیء، آن چند خط کد محاسباتی اجرا خواهند شد.
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyClass myClass = new MyClass();
}
}
نوشتن کدهای کلاس (class)، در حالتی که کلاس به ورودی نیاز دارد :
برای حالتی که نیاز به یک یا چند ورودی داریم، دو روش مختلف را شرح می دهیم :
روش اول :
فرض کنید که همان محاسبات را بخواهیم انجام بدهیم، اما قصد داشته باشیم که دو عدد را از Activity دریافت کنیم، بنابراین، باید کدهای کلاس MyClass را به صورت زیر تغییر بدهیم :
import junit.framework.TestCase;
public class MyClass extends TestCase {
public int number3;
public MyClass (int number1, int number2) {
number3 = number1*number2;
}
}
در واقع ساختار زیر را به کدهای کلاس MyClass افزوده ایم :
محاسبات مورد نظرمان بر اساس ورودی های کلاس
}
بنابراین چنانچه بخواهیم کدهای کلاس MyClass را در یک Activity اجرا کنیم، باید دو ورودی نیز برای کلاس MyClass تعیین کنیم. یعنی کدهایی مشابه کدهای زیر را در میان کدهای Activity می نویسیم :
int myNumber2 = 30;
MyClass myClass = new MyClass(myNumber1, myNumber2);
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int myNumber1 = 20;
int myNumber2 = 30;
MyClass myClass = new MyClass(myNumber1, myNumber2);
}
}
روش دوم :
کدهای کلاس MyClass را به صورت زیر می نویسیم :
import junit.framework.TestCase;
public class MyClass extends TestCase {
public int number3;
public int Calculate (int number1, int number2) {
number3 = number1*number2;
return 1;
}
}
دقت شود که برای برگرداندن مقدار به Activity ، خط زیر را نوشته ایم، اما در واقع، ظاهری است و چون همیشه مقدار 1 را برمی گرداند، عملا آن را از کلاس MyClass دریافت نخواهیم کرد (یعنی کدهای Activity را به گونه ای می نویسیم که آن را ذخیره نکنیم) :
اکنون باید کدهای زیر را در میان کدهای Activity بنویسیم :
int myNumber2 = 30;
MyClass myClass = new MyClass();
myClass.Calculate(myNumber1, myNumber2);
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int myNumber1 = 20;
int myNumber2 = 30;
MyClass myClass = new MyClass();
myClass.Calculate(myNumber1, myNumber2);
}
}
نوشتن کدهای کلاس (class)، در حالتی که یک یا چند خروجی را به Activity برمی گرداند :
در حالت هایی که تا اینجا مثال زدیم، کلاس MyClass ، هیچ خروجی را به Activity برنمی گرداند، اما گاهی نیاز داریم که یک یا چند مقدار را از کلاس ساخته شده دریافت کنیم تا ادامه کدهای Activity ، بر اساس آنها اجرا شوند. برای این منظور، می توانیم کدهای کلاس MyClass را به صورت زیر بنویسیم :
import junit.framework.TestCase;
public class MyClass extends TestCase {
public int number3;
public int Calculate (int number1, int number2) {
number3 = number1*number2;
return number3;
}
}
با عبارت زیر، مقدار number3 را به Activity بر می گردانیم (کلمه return را به خاطر بسپارید) :
اکنون برای اینکه کدهای کلاس MyClass در Activity مورد نظرمان اجرا شوند و نتیجه را هم از کلاس MyClass دریافت کنیم، باید کدهای زیر را در میان کدهای Activity بنویسیم :
int myNumber2 = 30;
MyClass myClass = new MyClass();
int myNumber3 = myClass.Calculate(myNumber1, myNumber2);
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int myNumber1 = 20;
int myNumber2 = 30;
MyClass myClass = new MyClass();
int myNumber3 = myClass.Calculate(myNumber1, myNumber2);
}
}
برگرداندن بیش از یک خروجی، توسط کلاس (class) :
چنانچه بخواهیم که کلاس MyClass ، بیش از یک خروجی را به Activity برگرداند، کدهای کلاس MyClass می تواند به صورت زیر نوشته شود (برای حالت دو خروجی) :
import junit.framework.TestCase;
public class MyClass extends TestCase {
public int[] numbers = new int [2];
public int[] Calculate (int number1, int number2) {
numbers[0] = number1*number2;
numbers[1] = 2*number1;
return numbers;
}
}
مشاهده می کنید که این بار، مقادیر را در یک آرایه از جنس int قرار داده ایم (تعداد عناصر آرایه حتما باید در همان ابتدای تعریف، مشخص شود).
برای دریافت دو مقدار (به صورت عناصر ذخیره شده در یک آرایه)، کدهای زیر را در میان کدهای Activity می نویسیم :
int myNumber2 = 30;
MyClass myClass = new MyClass();
int[] myNumbers = myClass.Calculate(myNumber1, myNumber2);
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int myNumber1 = 20;
int myNumber2 = 30;
MyClass myClass = new MyClass();
int[] myNumbers = myClass.Calculate(myNumber1, myNumber2);
}
}
دریافت Context مربوط به Activity توسط کلاس (class)، برای مواردی که در کدها باید Activity شناسایی شود :
در برخی از کدها، باید Activity شناسایی شود تا کدها به صورت صحیح اجرا گردند. مثلا فرض کنید کدهای یک Activity به صورت زیر باشد :
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(MainActivity.this, "www.kelidestan.com", Toast.LENGTH_SHORT).show();
}
}
همان طور که مشاهده می کنید، کد زیر را نوشته ایم که برای نمایش یک پیام کوتاه به کاربر به کار می رود :
اگر این خط از کدها را در یک کلاس (class) بنویسیم، دیگر نمی تواند با استفاده از عبارت MainActivity.this ، به Context متناظر با Activity دسترسی پیدا کند (آن را بشناسد)، بنابراین باید Context مربوط به Activity را به آن کلاس بفرستیم. بنابراین، کدهای کلاس MyClass را به صورت زیر می نویسیم :
import junit.framework.TestCase;
import android.content.Context;
import android.widget.Toast;
public class MyClass extends TestCase {
private Context context;
public MyClass (Context context) {
this.context = context;
Toast.makeText(this.context, "www.kelidestan.com", Toast.LENGTH_SHORT).show();
}
}
کد زیر را باید در میان کدهای Activity بنویسیم :
در کد بالا، کلمه this به Context مربوط به Activity اشاره می کند و بنابراین در حال ارسال Context مربوط به Activity به کلاس MyClass هستیم (ساخت یک شیء از کلاس MyClass).
کل کدهای Activity می تواند مشابه کدهای زیر باشد :
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyClass myClass = new MyClass(this);
}
}