بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

یک کار گروهی برای یادگیری Reflection

مدیریت گفتگو
uncocoder 12 سال پیش
آخرین تغییر: 11 سال پیش

بعضی از دوستان هستند که من بهشون این راه رو یاد دادم، پس اونها چیزی ننویسن، کسانی که تحقیق می کنن بنویسن تا با تحقیق به نتیجه برسید.

داخل متد parseGui رو به نحوی پر کنید که خودش بره برای شما عناصر UI نام برده شده در کلاس Ui رو بگیره، به نوع مناسبش Cast کنه و داخل فیلد بریزه. نصف راه رو من می نویسم:

public SampleActivity extends Activity {
public Ui ui;

public class Ui {
public TextView txtTitle;
public Button btnAction;

public Ui(View view){
HelperUi.parseGui(view);
}
}

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.some_layout);

ui = new Ui(getWindow().getDecoreView());

ui.btnAction.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
ui.txtTitle.setText("Sample");
}
});
}
}

نظرات

uncocoder 12 سال پیش
بچه ها من کد رو رو هوا نوشتم، ممکنه ایراد های Syntax داشته باشه. توجه کنید که کار خیلی راحت شد چون الان فقط شما باید داخل parseGui رو بنویسید.
Spirit 12 سال پیش
من تونستم id و نوع تمام viewـهای layoutـه اکتیوتی رو دربیارم ، به علاوه متغیر ها کلاس UI رو ، حالا نمیتونم اینا رو باهم قاطی کنم :D
AllahYar 12 سال پیش
استاد چه خروجی داره ؟ getWindow().getDecoreView()
uncocoder 12 سال پیش
تحقیق کنید البته در آموزشها استفاده هم شده. خروجی View هست.
AllahYar 12 سال پیش
استاد تحقیق کردم نتیجه ای نگرفتم بعد یه سوال اینو تحقیق نکردم تابعی نیست به صورت آرایه تمام ایدهای لی اوت رو بهم بده و من برای کلاسم صفت بسازم و همون صفت رو کست کنم ؟
uncocoder 12 سال پیش
پاسخ آقای حسین زاده رو ببینید، تقریباً از همین روش استفاده کردن.
طاهر 12 سال پیش
getWindow().getDecoreView() این قسمت view جاری رو برمیگردونه درسته ؟
طاهر 12 سال پیش
برای من که یه خورده گنگ هست در صورت امکان سوال رو بازتر کنید

پاسخ‌ها 3

محمد حسین زاده 12 سال پیش

این راه رو پیشنهاد میدم

 public class ReflectionSampleActivity extends Activity {

public TextView txtSample;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

UiParser.parse(this);

txtSample.setText("Hi! from java reflection ...");
}
}

با داشتن اکتیویتی و ارسالش به parser میشه به این مقصود رسید

 public class UiParser {

private static Hashtable<Class<? extends Activity>, StructCachedActivity> _cacheViews =
new Hashtable<Class<? extends Activity>, StructCachedActivity>();

public static void parse(Activity activity) {

if (_cacheViews.containsKey(activity.getClass())) {

loadFields(_cacheViews.get(activity.getClass()), activity);

return;
}

StructCachedActivity cachedActivity = new StructCachedActivity();

cachedActivity.activity = activity.getClass();

cachedActivity.view = activity.getWindow().getDecorView();

Field[] fields = activity.getClass().getDeclaredFields();

for (Field field : fields)

cachedActivity.fields.put(field.getName(), field);

cachedActivity.context = activity.getBaseContext();

if (cachedActivity.context != null)

cachedActivity.resources = cachedActivity.context.getResources();

getAllViews(cachedActivity, cachedActivity.view);

_cacheViews.put(activity.getClass(), cachedActivity);

loadFields(cachedActivity, activity);
}

private static void loadFields(StructCachedActivity cachedActivity,
Activity activity) {

try {

for (String key : cachedActivity.fields.keySet()) {

Field field = cachedActivity.fields.get(key);

View control = cachedActivity.controls.containsKey(key) ? cachedActivity.controls
.get(key) : null;

if (control.equals(null))

continue;

field.set(activity, cachedActivity.controls.get(key));
}

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

private static void getAllViews(StructCachedActivity activity, View root) {

String id = getId(activity, root);

if (!id.equals(""))

activity.controls.put(getId(activity, root), root);

if (root instanceof ViewGroup) {

ViewGroup viewGroup = (ViewGroup) root;

for (int i = 0; i < viewGroup.getChildCount(); i++)

getAllViews(activity, viewGroup.getChildAt(i));
}
}

private static String getId(StructCachedActivity activity, View view) {

String entryName = "";

int id = view.getId();

if (id == 0xffffffff)

return entryName;

if (activity.resources != null)

entryName = activity.resources.getResourceEntryName(id);

return entryName;
}

}

به این خاطر که اکتیویتی های برنامه در زمان اجرا تغییری نمیکنن یه سیستم کش در نظر میگیریم که سربار رو به حد اقل برسونیم. سیستم کش این ساختار رو داره :

 public class StructCachedActivity {
public StructCachedActivity() {
controls = new Hashtable<String, View>();
fields = new Hashtable<String, Field>();
}

public Class<? extends Activity> activity;

public View view;

public Context context;

public Resources resources;

public Hashtable<String, Field> fields;

public Hashtable<String, View> controls;

}

تنها نکته اینه که فیلد همنام آیدی کنترل و به صورت public تعریف میشه

نظرات

uncocoder 12 سال پیش
بعضی جاهاش یک گریزی به Reflection زده اما سورس اصلی و خوب می تونه تقریباً 20 خط باشه. دیگه جوابی نبود؟
AllahYar 12 سال پیش
مای گاد این همه دنگ و فنگ زوره به خدا داکیومنت درست و حسابی هم نداره :(
uncocoder 12 سال پیش
آموزش ویدئویی تدوین شد.
uncocoder 12 سال پیش

با توجه به تدوین شدن موضوع سئوال در آموزشها ویدئویی، ابتدا آنرا مطالعه و تمرین کنید و سپس برای تمرین خودتان به اهداف زیر برسید:

اهداف قابل رسیدن

  1. دسترسی به فیلدهای هر کلاسی که خواستید و نه تنها کلاسی که از آن extends شده است.
  2. دسترسی به فیلدهای Private هر کلاسی که خواستید.
  3. صدا زدن یک متد static و یک متد non-static از یک کلاس دلخواه.
  4. گرفتن لیست متدهای داخل یک کلاس.
  5. گرفتن لیست متدهای final شده یک کلاس.
  6. ساخت یک annotation اختصاصی.
  7. پیدا کردن تمامی فیلدهایی که دارای annotation خاصی هستند.
  8. پیدا کردن تمامی متدهایی که دارای annotaion خاصی هستند.
  9. ذکر چند parameter برای annotation و دسترسی با reflection به خواص آن.
  10. ...

 

زمان معقول برای پیاده سازی تمامی امکانات بالا و مسلط شدن به آن

حدود 3 ماه روزی 8 ساعت

نظرات

MiRHaDi 12 سال پیش
3 ماه روزی 8 ساعت !؟ 720 ساعت ؟ پس یعنی یاد گیریش برامون بیش از 10 15 میلیون ارزش افزوده داره !؟
Ali 11 سال پیش

تمرینی که استاد تعریف کردند رو من به صورت زیر نوشتم اما احتمالا مشکلاتی داره یا اصلا اون چیزی نیست که استاد مدنظرشون بود چون خیلی زودتر از اون زمانی که استاد تعیین کردند نوشتم. خوشحال میشم مشکلاتش رو بگید یا اگر راه بهتری هست معرفی کنید.

 public class Helper {

private static Object classInstance = null;
private static String string = null;


// 1, 2
public Object getMyField(Class<?> clazz, String fieldName) {
Object myField = null;
try {
for (Field field: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredFields()) {
field.setAccessible(true);
if (field.getName().equals(fieldName)) {
if (classInstance == null || !string.equals(clazz.getSimpleName())) {
string = clazz.getSimpleName();
classInstance = clazz.newInstance();
}
myField = field.get(classInstance);
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
return myField;
}


// 1, 2
public void setMyField(Class<?> clazz, String fieldName, Object newValue) {
try {
for (Field field: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredFields()) {
field.setAccessible(true);
if (field.getName().equals(fieldName)) {
if (classInstance == null || !string.equals(clazz.getSimpleName())) {
string = clazz.getSimpleName();
classInstance = clazz.newInstance();
}
field.set(classInstance, newValue);
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
}


// 3
public void invokeMyMethod(Class<?> clazz, String methodName, Object[] methodParameters) {
try {
for (Method method: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredMethods()) {
method.setAccessible(true);
if (method.getName().equals(methodName)) {
method.invoke(clazz.newInstance(), methodParameters);
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
}


// 4
public String getMyMethodList(Class<?> clazz) {
String methodsName = "No Method Found";
try {
for (Method method: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredMethods()) {
method.setAccessible(true);
methodsName = methodsName + method.getName() + ",";
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return methodsName;
}


// 5
public String getMyFinalMethodList(Class<?> clazz) {
String methodsName = "No Method Found";
try {
for (Method method: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredMethods()) {
method.setAccessible(true);
if (Modifier.isFinal(method.getModifiers())) {
methodsName = methodsName + method.getName() + ",";
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return methodsName;
}


// 7
public String findMyFieldAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
String fieldsName = "No Field Found";
try {
for (Field field: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getFields()) {
field.setAccessible(true);
if (field.isAnnotationPresent(annotationClazz)) {
try {
fieldsName = fieldsName + field.getName() + ",";
}
catch (Throwable e) {
e.printStackTrace();
}
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return fieldsName;
}


// 8
public String findMyMethodAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClazz) {
String methodsName = "No Method Found";
try {
for (Method method: clazz
.getClassLoader()
.loadClass(clazz.getName())
.getDeclaredMethods()) {
method.setAccessible(true);
if (method.isAnnotationPresent(annotationClazz)) {
try {
methodsName = methodsName + method.getName() + ",";
}
catch (Throwable e) {
e.printStackTrace();
}
}
}
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return methodsName;
}
}

نظرات

Ali 11 سال پیش
کسی نظری نداشت :|

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .