Skip to content

۱. بایپس محدودیت‌های گرافیکی (UI Thread) ​

در اندروید، شما نمی‌توانید از داخل ترد (Thread) فریدا، مستقیما ویژگی‌های ظاهری اپلیکیشن (مثل فعال کردن یک دکمه) را تغییر دهید. اگر این کار را بکنید، اپلیکیشن با خطای CalledFromWrongThreadException کرش می‌کند.

برای تغییر در رابط کاربری، باید کد خود را به ترد اصلی (UI Thread) اپلیکیشن بفرستید.

سناریو: فعال کردن دکمه‌های غیرفعال (Disabled Buttons) ​

فرض کنید دکمه "پرداخت" یا "ورود" به دلیل چک‌های امنیتی خاکستری و غیرفعال شده است. ما آن را به زور فعال می‌کنیم.

کد جاوا (وضعیت دکمه):

java
/* در فایل layout یا کد جاوا: */
Button loginButton = findViewById(R.id.btn_login)
loginButton.setEnabled(false) // دکمه غیرفعال است
loginButton.setVisibility(View.GONE) // دکمه مخفی است

کد فریدا (اجرا در UI Thread):

javascript
Java.perform(function () {
    var bClass = Java.use("android.widget.Button")
    var View = Java.use("android.view.View")

    /* پیدا کردن دکمه در حافظه (استفاده از Java.choose چون نمونه زنده را می‌خواهیم) */    
    Java.choose("android.widget.Button", {
        onMatch: function (instance) {
            /* چک کردن اینکه آیا این همان دکمه مورد نظر ماست (مثلا از روی متن دکمه) */            
            if (instance.getText().toString() === "Login") {
                
                console.log("[*] Found the button! Sending command to UI Thread...")

                /* اجرای کد در ترد اصلی اندروید برای جلوگیری از کرش */                
                var Runnable = Java.use("java.lang.Runnable")
                var MyRunnable = Java.registerClass({
                    name: 'com.hacker.uithread',
                    implements: [Runnable],
                    methods: {
                        run: function () {
                            instance.setEnabled(true) // فعال کردن دکمه
                            instance.setVisibility(View.VISIBLE.value) // نمایش دکمه
                            console.log("[+] Button is now ENABLED and VISIBLE!")
                        }
                    }
                })

                /* ارسال به ترد اصلی */                
                var currentActivity = Java.use("android.app.ActivityThread").currentActivityThread().mActivities().value.at(0).value.activity.value
                currentActivity.runOnUiThread(MyRunnable.$new())
            }
        },
        onComplete: function () {}
    })
})