آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

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

uncocoder  12 سال پیش  10 سال پیش
+21 0

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

داخل متد 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");
}
});
}
}
+1 0
بچه ها من کد رو رو هوا نوشتم، ممکنه ایراد های Syntax داشته باشه. توجه کنید که کار خیلی راحت شد چون الان فقط شما باید داخل parseGui رو بنویسید. (12 سال پیش)
0 0
من تونستم id و نوع تمام viewـهای layoutـه اکتیوتی رو دربیارم ، به علاوه متغیر ها کلاس UI رو ، حالا نمیتونم اینا رو باهم قاطی کنم :D (12 سال پیش)
0 0
استاد چه خروجی داره ؟ getWindow().getDecoreView() (12 سال پیش)
0 0
تحقیق کنید البته در آموزشها استفاده هم شده. خروجی View هست. (12 سال پیش)
0 0
استاد تحقیق کردم نتیجه ای نگرفتم بعد یه سوال اینو تحقیق نکردم تابعی نیست به صورت آرایه تمام ایدهای لی اوت رو بهم بده و من برای کلاسم صفت بسازم و همون صفت رو کست کنم ؟ (12 سال پیش)
0 0
پاسخ آقای حسین زاده رو ببینید، تقریباً از همین روش استفاده کردن. (12 سال پیش)
0 0
getWindow().getDecoreView() این قسمت view جاری رو برمیگردونه درسته ؟ (12 سال پیش)
0 0
برای من که یه خورده گنگ هست در صورت امکان سوال رو بازتر کنید (12 سال پیش)
0 0
مشترکــــــــــــــــــــــــــــ (12 سال پیش)
0 0
مشترکـــــــ :| (12 سال پیش)
 برای این سوال 3 پاسخ وجود دارد.
پاسخ به سوال 
محمد حسین زاده  12 سال پیش
+7 0

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

 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 تعریف میشه

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

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

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

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

 

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

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

0 0
3 ماه روزی 8 ساعت !؟ 720 ساعت ؟ پس یعنی یاد گیریش برامون بیش از 10 15 میلیون ارزش افزوده داره !؟ (12 سال پیش)
پاسخ به سوال 
Ali  10 سال پیش
+2 0

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

 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;
}
}
0 0
کسی نظری نداشت :| (10 سال پیش)

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