আমরা কীভাবে অ্যান্ড্রয়েডে রানঅনউইথ্রেড ব্যবহার করব?


157

আমি অ্যান্ড্রয়েডে নতুন এবং আমি ইউআই-থ্রেডটি ব্যবহার করার চেষ্টা করছি, তাই আমি একটি সাধারণ পরীক্ষার ক্রিয়াকলাপ লিখেছি। তবে আমি মনে করি আমি কিছু ভুল বুঝেছি, কারণ বোতামটি ক্লিক করার পরে - অ্যাপটি আর সাড়া দেয় না

public class TestActivity extends Activity {

    Button btn;
    int i = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                runThread();
            }
        });
    }

    private void runThread(){
        runOnUiThread (new Thread(new Runnable() {  
            public void run() {
                while(i++ < 1000){
                    btn.setText("#"+i);
                    try {
                        Thread.sleep(300);
                    } 
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
             }
        }));
    }
}

উত্তর:


204

নীচে runThreadফাংশন স্নিপেট সংশোধন করা হয় ।

private void runThread() {

    new Thread() {
        public void run() {
            while (i++ < 1000) {
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            btn.setText("#" + i);
                        }
                    });
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}

এটি প্রায় অবিলম্বে আবর্জনা সংগ্রহ করা হয়নি? সম্ভবত আপনাকে থ্রেড ()
নিক

14
@ নিক: আবর্জনা সংগ্রহকারীরা স্ট্যাকটিও লক্ষ্য করে, অর্থাৎ থ্রেডটি চলতে থাকলে, এটি জিসি'ড পাবে না।
মিরো ক্রপাসেক

@ বিপুল, আমার ফোনের আবর্তনের বিষয়ে একটি প্রশ্ন ছিল: আমি একবার চাই আমার ফোনটি ঘোরানোর পরে এই থ্রেডটি চলে এবং কোনও নতুন থ্রেড তৈরি হয় না। ফোনটি একবার ঘোরানোর সাথে সাথে কীভাবে নতুন থ্রেড তৈরি করা রোধ করা যায় সে সম্পর্কে আপনি কিছু ইঙ্গিত সরবরাহ করতে পারেন?
ব্যবহারকারী 1836957

89

কেবল এটি একটি ফাংশন হিসাবে মোড়ানো, তারপরে আপনার পটভূমি থ্রেড থেকে এই ফাংশনটি কল করুন।

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}

3
বাইরের স্কোপে ( final)
মেরিওটোমো

27

আপনি এটি সামনে থেকে সামনে আছে। আপনার বোতামটি ক্লিক করার জন্য একটি কল ক্লিক করে runOnUiThread(), তবে এটির প্রয়োজন নেই, যেহেতু ক্লিক হ্যান্ডলারটি ইতিমধ্যে ইউআই থ্রেডে চলছে। তারপরে, আপনার কোডটি runOnUiThread()একটি নতুন পটভূমি থ্রেড চালু করছে, যেখানে আপনি ইউআই অপারেশন করার চেষ্টা করছেন, যা পরে ব্যর্থ হয়।

পরিবর্তে, কেবল আপনার ক্লিক হ্যান্ডলার থেকে ব্যাকগ্রাউন্ড থ্রেডটি সরাসরি চালু করুন। তারপর, কল মোড়ানো btn.setText()একটি কল ভিতরে runOnUiThread()


যদিও এটি সত্য যে ক্লিক হ্যান্ডলারটি ইতিমধ্যে ইউআই থ্রেডে রয়েছে, কল করার জন্য runOnUiThread()এটি অপ্রয়োজনীয় তবে এটি নিরীহ হতে হবে। সেই পদ্ধতির জাভাদোক বলেছেন "UI থ্রেডে নির্দিষ্ট ক্রিয়াটি চালিত করে current যদি বর্তমান থ্রেডটি UI থ্রেড হয় তবে ক্রিয়াটি তত্ক্ষণাত্ কার্যকর করা হবে If যদি বর্তমান থ্রেডটি UI থ্রেড না হয় তবে ক্রিয়াটি ইভেন্টের সারিতে পোস্ট করা হবে ইউআই থ্রেডের। "
k2col


10

রানওনউইথ্রেড () ব্যবহার করে বেশ কয়েকটি কৌশল রয়েছে, সমস্ত দেখতে দিন

এটিকে আমার মূল থ্রেড (ইউআই থ্রেড) বলা হয় অ্যান্ড্রয়েড বেসিক থ্রেডঅ্যাক্টিভিটি এবং আমি এটি বিভিন্ন উপায়ে কর্মী থ্রেড থেকে আপডেট করতে যাচ্ছি -

public class AndroidBasicThreadActivity extends AppCompatActivity
{
    public static TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_basic_thread);

        textView = (TextView) findViewById(R.id.textview);

        MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
        Thread t1 = new Thread(myTask, "Bajrang");
        t1.start();
    }
}

1.) কর্মী থ্রেডে আর্গুমেন্ট হিসাবে ক্রিয়াকলাপের উদাহরণটি পাশ করে

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {

        //perform heavy task here and finally update the UI with result this way - 
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
            }
        });
    }
}

২) কর্মী থ্রেডে ভিউয়ের পোস্ট (চলমান রানযোগ্য) পদ্ধতি ব্যবহার করে

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {
     //perform heavy task here and finally update the UI with result this way - 
       AndroidBasicThreadActivity.textView.post(new Runnable()
      { 
        @Override
        public void run()
        {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });

    }
}

৩) অ্যান্ড্রয়েড.ওস প্যাকেজ থেকে হ্যান্ডলার ক্লাস ব্যবহার করে যদি আমাদের কাছে প্রসঙ্গটি (এই / getApplicationContext ()) বা ক্রিয়াকলাপের উদাহরণ (AndroidBasicThreadActivity.this) না থাকে তবে আমাদের নীচের মত হ্যান্ডলার ক্লাস ব্যবহার করতে হবে -

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
   public void run()
  {
  //perform heavy task here and finally update the UI with result this way - 
  new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });
  }
}

আপনাকে ধন্যবাদ .. ক্রিয়াকলাপের রানডউনড্রেড সম্পর্কে কেবল পুনরাবৃত্তি করার পরিবর্তে, আপনি এটিকে আহ্বান করার সমস্ত সম্ভাব্য উপায় উল্লেখ করেছেন ..
অরুন

আপনাকে ধন্যবাদ .. ক্রিয়াকলাপের রানডউনড্রেড সম্পর্কে কেবল পুনরাবৃত্তি করার পরিবর্তে, আপনি এটিকে আহ্বান করার সমস্ত সম্ভাব্য উপায় উল্লেখ করেছেন ..
অরুন

6

যদি খণ্ডে ব্যবহার করে থাকেন তবে কেবল লিখুন

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do something on UiThread
    }
});

1

এই তোমার:

@UiThread
    public void logMsg(final String msg) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Log.d("UI thread", "I am the UI thread");


            }
        });
    }

1

আমরা অ্যাপ্লিকেশনগুলিকে মসৃণ করতে এবং এএনআর এড়ানোর জন্য ওয়ার্কার থ্রেড ব্যবহার করি। কর্মী ট্র্যাডে ভারী প্রক্রিয়া শেষে আমাদের ইউআই আপডেট করতে হবে। ইউআই কেবলমাত্র ইউআই থ্রেড থেকে আপডেট করা যেতে পারে। এই জাতীয় ক্ষেত্রে, আমরা হ্যান্ডলার ব্যবহার করি বা রানঅনুআইথ্রেড উভয়েরই একটি রান্নেবল রান পদ্ধতি রয়েছে যা ইউআই থ্রেডে কার্যকর করে। অনক্লিক পদ্ধতিটি ইউআই থ্রেডে চলে তাই এখানে রানঅনউইথ্রেড ব্যবহার করার দরকার নেই।

কোটলিন ব্যবহার করা

ক্রিয়াকলাপের সময়,

this.runOnUiThread {
      // Do stuff
}

খণ্ড থেকে,

activity?.runOnUiThread {
      // Do stuff
}

জাভা ব্যবহার করে ,

this.runOnUiThread(new Runnable() {
     void run() {
         // Do stuff
     }
});

0

আপনি এই নমুনা থেকে ব্যবহার করতে পারেন:

নিম্নলিখিত উদাহরণে, আমরা এই সুবিধাটি একটি পটভূমি থ্রেড দ্বারা প্রক্রিয়াজাত একটি প্রতিশব্দ অনুসন্ধান থেকে ফলাফল প্রকাশ করতে ব্যবহার করতে যাচ্ছি।

অনক্রিয়েট ক্রিয়াকলাপ কলব্যাকের সময় লক্ষ্যটি অর্জন করতে, আমরা একটি তৈরি থ্রেডে অনুসন্ধানটাস্ক চালানোর জন্য অন ক্লিকলিস্টনার সেট করব set

ব্যবহারকারী যখন অনুসন্ধান বোতামে ক্লিক করে, আমরা একটি রান্নেবল বেনাম শ্রেণি তৈরি করব যা আর.আইড.ওয়ার্ডএইট সম্পাদনা পাঠ্য টাইপ করা শব্দের জন্য অনুসন্ধান করে এবং রান্নেবল কার্যকর করতে থ্রেড শুরু করে।

অনুসন্ধানটি শেষ হলে, আমরা ইউআই থ্রেডের প্রতিশব্দ টেক্সটভিউতে ফলাফলটি প্রকাশের জন্য রান্নেবল সেটসাইনাম রিসাল্টের একটি উদাহরণ তৈরি করব।

এই কৌশলটি কখনও কখনও সর্বাধিক সুবিধাজনক নয়, বিশেষত যখন আমাদের কোনও ক্রিয়াকলাপ উদাহরণে অ্যাক্সেস না থাকে; অতএব, নিম্নলিখিত অধ্যায়গুলিতে, আমরা ব্যাকগ্রাউন্ড কম্পিউটিং কার্য থেকে ইউআই আপডেট করার জন্য সহজ এবং ক্লিনার কৌশলগুলি নিয়ে আলোচনা করব।

public class MainActivity extends AppCompatActivity {

    class SetSynonymResult implements Runnable {
        String synonym;

        SetSynonymResult(String synonym) {
            this.synonym = synonym;
        }

        public void run() {
            Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
                    synonym, Thread.currentThread().getId()) + " !");
            TextView tv = (TextView) findViewById(R.id.synonymTv);
            tv.setText(this.synonym);
        }
    }

    ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button search = (Button) findViewById(R.id.searchBut);
        final EditText word = (EditText) findViewById(R.id.wordEt);
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Runnable searchTask = new Runnable() {
                    @Override
                    public void run() {
                        String result = searchSynomim(word.getText().toString());
                        Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
                                word.getText(), Thread.currentThread().getName()));
                        runOnUiThread(new SetSynonymResult(result));
                    }
                };
                Thread thread = new Thread(searchTask);
                thread.start();
            }
        });

    }

    static int i = 0;

    String searchSynomim(String word) {
        return ++i % 2 == 0 ? "fake" : "mock";
    }
}

সূত্র :

অ্যাসিনক্রোনাস অ্যান্ড্রয়েড প্রোগ্রামিং হেল্ডার ভাসকনস্লোস



0
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.success1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        gifImageView.setGifImageResource(R.drawable.success);
                    }
                });

            }
        }).start();

    }

0

এটা চেষ্টা কর: getActivity().runOnUiThread(new Runnable...

ইহার কারণ:

1) আপনার রানআউনইথ্রেডে অন্তর্ভুক্ত এটি আপনার খণ্ডকে নয়, অ্যাসিঙ্কটাস্ককে উল্লেখ করছে ।

2) টুকরাটির রানঅনউথ্রিড নেই।

তবে ক্রিয়াকলাপটি করে।

দ্রষ্টব্য যে আপনি যদি ইতিমধ্যে মূল থ্রেডে থাকেন তবে ক্রিয়াকলাপটি কেবল রান্নেবলকে কার্যকর করে, অন্যথায় এটি হ্যান্ডলার ব্যবহার করে। আপনি যদি এর প্রসঙ্গে উদ্বিগ্ন হতে না চান তবে আপনি নিজের খণ্ডে কোনও হ্যান্ডলার বাস্তবায়ন করতে পারেন, এটি আসলে খুব সহজ:

// একটি শ্রেণীর উদাহরণ

private Handler mHandler = new Handler(Looper.getMainLooper());

// আপনার কোড অন্য কোথাও

mHandler.post(<your runnable>);

// ^ এটি সর্বদা মূল থ্রেডের পরবর্তী রান লুপে চালানো হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.