অ্যান্ড্রয়েডে আমি কীভাবে একটি পটভূমি থ্রেডে কোড চালাতে পারি?


131

অবিচ্ছিন্নভাবে আমি কিছু কোড চালিয়ে যেতে চাই in আমি এটি কোনও পরিষেবাতে করতে চাই না। অন্য কোন উপায় কি সম্ভব?

আমি Threadক্লাসটি কল করার চেষ্টা করেছি Activityকিন্তু আমার Activityঅবশিষ্টাংশগুলি কিছু সময়ের জন্য পটভূমিতে রয়েছে এবং পরে এটি বন্ধ হয়ে যায়। Threadশ্রেণী কাজ করার স্টপ।

class testThread implements Runnable {
        @Override
        public void run() {
            File file = new File( Environment.getExternalStorageDirectory(), "/BPCLTracker/gpsdata.txt" );
            int i = 0;

            RandomAccessFile in = null;

            try {
                in = new RandomAccessFile( file, "rw" );
            } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            }
//String line =null;
            while ( true ) {
                HttpEntity entity = null;
                try {
                    if ( isInternetOn() ) {
                        while ( ( line = in.readLine() ) != null ) {

                            HttpClient client = new DefaultHttpClient();
                            String url = "some url";
                            HttpPost request = new HttpPost( url );
                            StringEntity se = new StringEntity( line );
                            se.setContentEncoding( "UTF-8" );
                            se.setContentEncoding( new BasicHeader( HTTP.CONTENT_TYPE, "application/json" ) );
                            entity = se;
                            request.setEntity( entity );
                            HttpResponse response = client.execute( request );
                            entity = response.getEntity();
                            i++;
                        }
                        if ( ( line = in.readLine() ) == null && entity != null ) {
                            file.delete();
                            testThread t = new testThread();
                            Thread t1 = new Thread( t );
                            t1.start();
                        }


                    } else {
                        Thread.sleep( 60000 );
                    } // end of else

                } catch (NullPointerException e1) {
                    e1.printStackTrace();
                } catch (InterruptedException e2) {
                    e2.printStackTrace();
                } catch (IOException e1) {
// TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }// end of while
        }// end of run

    }

1
ওহে. আপনি যা চেষ্টা করেছেন তার উদাহরণ হিসাবে আপনি কিছু কোড পোস্ট করতে পারেন? ব্যাকগ্রাউন্ড থ্রেডে কোড চালানোর বিভিন্ন উপায় রয়েছে তবে আপনাকে অবশ্যই মনে রাখতে হবে আপনি যদি কোনও ইউআই উপাদান অ্যাক্সেস করছেন তবে আপনাকে অবশ্যই runOnUiThread()পদ্ধতিটি ব্যবহার করে ইউআই থ্রেডে অ্যাক্সেস করতে হবে ।
অ্যালেক্স উইস


এটি তাই প্রস্তাবিত হয় না। অবিচ্ছিন্নভাবে চালানো ডিভাইসের ব্যাটারি নিষ্কাশন করবে।
হেলমিবি 18'13

আমি কোডটি পাঠিয়েছি।
ব্যবহারকারী 2082987

আমি এটি পরিষেবাতে ব্যবহার করার চেষ্টা করেছি তবে এটি একই রেকর্ডটি একাধিকবার প্রেরণ করেছে।
ব্যবহারকারী 2082987

উত্তর:


379

আপনি প্রয়োজন হলে:

  1. একটি পটভূমি থ্রেডে কোড চালাও

  2. কোডটি কার্যকর করুন যা ইউআইকে স্পর্শ / আপডেট করে না

  3. কার্যকর করুন (সংক্ষিপ্ত) কোড যা সম্পূর্ণ হতে কয়েক সেকেন্ড সময় নেয়

তারপরে নিম্নলিখিত পরিষ্কার এবং দক্ষ প্যাটার্ন ব্যবহার করুন যা AsyncTask ব্যবহার করে:

AsyncTask.execute(new Runnable() {
   @Override
   public void run() {
      //TODO your background code
   }
});

10
দ্রষ্টব্য: এপিআই স্তরের 11 এর প্রয়োজন
ফ্রাইডারব্লিউমেল

9
আপনি নিম্নোক্ত ওজনের নিম্নোক্তটি কেন ব্যবহার করবেন না: নতুন থ্রেড (নতুন রান্নেবল () {@ ওভাররাইড পাবলিক অকার্যকর রান () {// ব্যাকগ্রাউন্ড কোড}})।
পুরষ্কার

3
এর ফলে স্মৃতি ফাঁস হওয়ার সম্ভাবনা আছে কি?
হিলফ্রিটজ

5
একটি বিষয় লক্ষণীয় যে অ্যাসিঙ্কটাস্কগুলি নির্ধারিত। আপনি যদি এটি সার্ভার এপিআই কলগুলির একগুচ্ছ জন্য ব্যবহার করেন তবে সেগুলি সমান্তরালে চলবে না।
চেজ রবার্টস


45

চলমান পটভূমি মনে রাখবেন, অবিচ্ছিন্নভাবে চালানো দুটি পৃথক কাজ।

দীর্ঘমেয়াদী পটভূমি প্রক্রিয়াগুলির জন্য, থ্রেডগুলি অ্যান্ড্রয়েডের সাথে অনুকূল নয়। তবে কোডটি এখানে দেওয়া এবং নিজের ঝুঁকিতে এটি করুন ...

মনে রাখবেন সার্ভিস বা থ্রেড পটভূমিতে চলবে তবে আপডেট পাওয়ার জন্য আমাদের টাস্কটির ট্রিগার করা (বারবার কল করা) দরকার, অর্থাৎ টাস্কটি শেষ হয়ে গেলে আমাদের পরবর্তী আপডেটের জন্য ফাংশনটি পুনরায় কল করতে হবে।

টাইমার (পর্যায়ক্রমিক ট্রিগার), অ্যালার্ম (টাইমবেস ট্রিগার), ব্রডকাস্ট (ইভেন্ট বেস ট্রিগার), পুনরাবৃত্তি আমাদের ফাংশন জাগিয়ে তুলবে।

public static boolean isRecursionEnable = true;

void runInBackground() {
    if (!isRecursionEnable)
        // Handle not to start multiple parallel threads
        return;

    // isRecursionEnable = false; when u want to stop
    // on exception on thread make it true again  
    new Thread(new Runnable() {
        @Override
        public void run() {
            // DO your work here
            // get the data
            if (activity_is_not_in_background) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // update UI
                        runInBackground();
                    }
                });
            } else {
                runInBackground();
            }
        }
    }).start();
}

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

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

একক বিবৃতিতে, আপনি যদি রানটি পটভূমির কাজটি চালিয়ে যেতে চান তবে আপনাকে স্টিকি সার্ভিস চালু করতে হবে এবং ইভেন্টের ভিত্তিতে পরিষেবাটিতে থ্রেড চালাতে হবে


ইউআই থ্রেড আপডেট করার জন্য প্রতি সেকেন্ডে একবার শ্রোতার কাছ থেকে মান ধরে নেওয়ার সময় আপনি কি গড়ে 20 মিনিটের জন্য পটভূমিতে একটি কাস্টম সিগন্যাল স্ট্রেন্থলাইজনটি চালানোর জন্য এই পদ্ধতির পরামর্শ দিন? এখানে আরো কনটেক্সট হয় stackoverflow.com/questions/36167719/...
JParks

আপনি যদি 'isRecursionEnable = true' সেট করেন তবে প্রক্রিয়াটি আবার কীভাবে চলবে? তারপরে আপনি 'रनইনব্যাকগ্রাউন্ড ()' এর জন্য 'রান' পদ্ধতির অভ্যন্তরে কল করবেন, ফাংশনের শুরুতে যদি এটি বিবৃতিটি প্রবেশ না করে তবে কীভাবে?
মিকি 13

23

অবিচ্ছিন্নভাবে আমি কিছু কোড চালিয়ে যেতে চাই in আমি এটি কোনও পরিষেবাতে করতে চাই না। অন্য কোন উপায় কি সম্ভব?

সম্ভবত আপনি যে মেকানিজমটি সন্ধান করছেন তা হ'ল AsyncTask। এটি সরাসরি ব্যাকগ্রাউন্ড থ্রেডে পটভূমি প্রক্রিয়া সম্পাদনের জন্য মনোনীত করা হয়েছে। এছাড়াও এর প্রধান উপকারিতা হ'ল কয়েকটি পদ্ধতি যা মেইন (ইউআই) থ্রেডে চলে এবং আপনার ইউআই আপডেট করতে সম্ভব করে যদি আপনি ব্যবহারকারীকে টাস্কের কিছু অগ্রগতি সম্পর্কে ঘোষণা করতে চান বা ব্যাকগ্রাউন্ড প্রক্রিয়া থেকে প্রাপ্ত তথ্য সহ ইউআই আপডেট করতে চান।

আপনি যদি না জানেন তবে এখানে কীভাবে শুরু করবেন তা চমৎকার টিউটোরিয়াল:

দ্রষ্টব্য: এছাড়াও সেই IntentServiceসাথে ResultReceiverকাজ করার সম্ভাবনাও রয়েছে।


@ user2082987 তাই আপনি এটি ব্যবহার করে দেখেছেন?
সাইমন ডরোসিয়াক

অ্যাসিঙ্কটাস্কের এই পরামিতিগুলি বিভ্রান্তিকর
ব্যবহারকারী 2082987

অ্যাসিঙ্কটাস্ক কোনওভাবেই থ্রেডের চারপাশে কেবল একটি মোড়ক, সুতরাং এটি ব্যাকগ্রাউন্ডে থাকা অবস্থায় অ্যান্ড্রয়েড অ্যাপ্লিকেশনটি মেরে ফেলার সমস্যাটি সমাধান করে না
ল্যাসি কিনুনেনেন

হাই @ ল্যাসিকিনুনেন আমি এই উত্তরটি 5 বছর আগে লিখেছি। এখন সমস্ত কিছু পরিবর্তিত হয়েছে এবং আমি বর্তমানে অ্যাসিঙ্কটাস্ক ব্যবহার করছি না কারণ এর স্মৃতিশক্তি ফাঁস নেই-নিরাপদ।
সাইমন ডোরোসিয়াক

হ্যাঁ আমি বুঝতে পেরেছি তবে লোকেরা এখনও এটি গুগলের মাধ্যমে খুঁজে পাবে এবং আমি গুগল র‍্যাপারগুলি ব্যবহার করার পরামর্শ দেওয়ার মতো বহু লোকের মন্তব্য দেখেছি যখন এটি কোনও উদ্দেশ্যহীন কাজ করে না, দুঃখিত। মূল প্রশ্নের হিসাবে যদি কেউ 2018 সালে কিছু উত্তর খুঁজছেন, একটি পরিষেবা তৈরি করুন এবং এটি চালু করুন এবং যদি আপনি এটি না খোলার সম্ভাবনা সর্বাধিক করতে চান তবে একটি বিজ্ঞপ্তি সহ এটি অগ্রভাগে হিসাবে চিহ্নিত করুন। আসল দীর্ঘ চলমান প্রক্রিয়া হ্যান্ডলার বা একটি পৃথক থ্রেড দিয়ে পরিচালনা করা যেতে পারে। তারা বুঝতে পারল না যে তারা আসলে এটিকে মেমরি ফাঁস না করে নিরাপদ করে তুলতে সক্ষম হয়েছে?
লাসি কিনুনেনেন

16

সরল 3-লাইনার

যে আমি দ্বারা একটি মন্তব্য হিসাবে পাওয়া এই কাজ করার একটি সহজ উপায় @awardak মধ্যে ব্র্যান্ডন অভদ্রতা উত্তর :

new Thread( new Runnable() { @Override public void run() { 
  // Run whatever background code you want here.
} } ).start();

আমি নিশ্চিত না, বা কীভাবে, AsyncTask.executeএটি ব্যবহারের চেয়ে ভাল তবে এটি আমাদের পক্ষে কাজ করে বলে মনে হয়। পার্থক্য হিসাবে কোনও মন্তব্য প্রশংসা করা হবে।

ধন্যবাদ, @ ওয়ার্ডক !


থ্রেডের রান পদ্ধতির অভ্যন্তরে এটি মূল থ্রেডে ফিরে পোস্ট করার জন্য আমরা হ্যান্ডেল.পোস্ট () পদ্ধতি ব্যবহার করি।
অ্যান্ড্রয়েডএক্সপি

2

অ্যাসিঙ্কটাস্কের একটি বিকল্প হ'ল রোবসপিস। https://github.com/octo-online/robospice

রোবসপিসের কয়েকটি বৈশিষ্ট্য।

1. সংক্ষিপ্ত আকারে (একটি পটভূমিতে AndroidService) নেটওয়ার্কের অনুরোধগুলি (উদাহরণ: স্প্রিং অ্যান্ড্রয়েড ব্যবহার করে REST অনুরোধগুলি)। ফলাফল প্রস্তুত হওয়ার পরে, ইউআই থ্রেডে আপনাকে অ্যাপটি জানান not

2.এর জোরালোভাবে টাইপ করা হয়! আপনি POJOs ব্যবহার করে আপনার অনুরোধগুলি করেন এবং আপনি অনুরোধ ফলাফল হিসাবে POJOs পান।

৩. অনুরোধের জন্য ব্যবহৃত POJOs তে বা আপনার প্রকল্পগুলিতে আপনি যে ক্রিয়াকলাপ শ্রেণি ব্যবহার করেন সেগুলিও সীমাবদ্ধ করবেন না।

4 কোডের ফলাফল (জ্যাকসন এবং জিসন, ​​বা এক্সএমএল, বা ফ্ল্যাট টেক্সট ফাইল, বা বাইনারি ফাইলগুলি এমনকি ওআরএম লাইট ব্যবহার করে জেসন)।

5. যদি আপনার কার্যক্রমগুলি (বা অন্য কোনও প্রসঙ্গে) নেটওয়ার্কের অনুরোধের ফলাফলের উল্লেখ করে এবং যদি তারা এখনও বেঁচে থাকে তবে

অ্যান্ড্রয়েড অ্যাসিঙ্কটাস্কগুলির বিপরীতে অ্যান্ড্রয়েড লোডারগুলির মতো মোটেও কোনও মেমরি ফাঁস, তাদের ইউআই থ্রেডে আপনার ক্রিয়াকলাপকে অবহিত করে।

7. একটি সাধারণ তবে শক্তিশালী ব্যতিক্রম হ্যান্ডলিং মডেল ব্যবহার করে।

নমুনা দিয়ে শুরু। https://github.com/octo-online/RoboSpice-samples

এ robospice একটি নমুনা https://play.google.com/store/apps/details?id=com.octo.android.robospice.motivations&feature=search_result


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

@ ইয়ার আপনি যদি কোনও অভিপ্রায় পরিষেবাটি দীর্ঘকাল ধরে চালনা করেন তবে এটি ব্যবহার করতে পারেন। এছাড়াও আপনি অ্যাসিনটাস্ক ব্যবহার করতে পারেন তবে এটি যদি অল্প সময়ের জন্য হয়। আপনি একটি থ্রেড তৈরি করতে পারেন এবং আপনার সমস্ত জিনিস সেখানে করতে পারেন। আমি দীর্ঘদিন ধরে রোবসপিস ব্যবহার করিনি। ভলির মতো অন্যান্য নেটওয়ার্কিং লাইব্রেরি রয়েছে ...
রঘুনন্দন

ঠিক আছে ধন্যবাদ. আমি রোবসপিস ব্যবহার সম্পর্কে ভেবেছিলাম, তবে দেখে মনে হচ্ছে এটি আমার প্রয়োজনের জন্য খুব ভাল (নমনীয়) নয়। আমি সাফল্যের সাথে দীর্ঘ সময় ধরে ইনটেন্স সার্ভিস ব্যবহার করি।
ইয়ার

2
class Background implements Runnable {
    private CountDownLatch latch = new CountDownLatch(1);
    private  Handler handler;

    Background() {
        Thread thread = new Thread(this);
        thread.start();
        try {
            latch.await();
        } catch (InterruptedException e) {
           /// e.printStackTrace();
        }
    }

    @Override
    public void run() {
        Looper.prepare();
        handler = new Handler();
        latch.countDown();
        Looper.loop();
    }

    public Handler getHandler() {
        return handler;
    }
}

5
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম। শুধুমাত্র কোড সহ উত্তরগুলি তারা "নিম্নমানের" হওয়ায় মুছে ফেলার জন্য পতাকাঙ্কিত হতে থাকে। প্রশ্নের উত্তর দেওয়ার ক্ষেত্রে সহায়তা বিভাগটি পড়ুন এবং তারপরে আপনার উত্তরে কিছু মন্তব্য যুক্ত করার বিষয়টি বিবেচনা করুন।
গ্রাহাম

0

আপনার যদি প্রয়োজন হয় বিভিন্ন কোড সহ পূর্ববর্তীভাবে থ্রেড চালানো উদাহরণস্বরূপ:

লিসেনার:

public interface ESLThreadListener {

    public List onBackground();

    public void onPostExecute(List list);

}

থ্রেড ক্লাস

public class ESLThread extends AsyncTask<Void, Void, List> {


    private ESLThreadListener mListener;

    public ESLThread() {

        if(mListener != null){

            mListener.onBackground();
        }
    }

    @Override
    protected List doInBackground(Void... params) {

        if(mListener != null){

            List list = mListener.onBackground();

            return list;
        }

        return null;
    }

    @Override
    protected void onPostExecute(List t) {
        if(mListener != null){

            if ( t != null) {
                mListener.onPostExecute(t);
            }
        }

    }


    public void setListener(ESLThreadListener mListener){

        this.mListener = mListener;
    }
}

বিভিন্ন কোড চালান:

  ESLThread thread = new ESLThread();
                        thread.setListener(new ESLThreadListener() {
                            @Override
                            public List onBackground() {
                                List<EntityShoppingListItems>  data = RoomDB.getDatabase(context).sliDAO().getSL(fId);

                                return data;

                            }

                            @Override
                            public void onPostExecute(List t) {

                                List<EntityShoppingListItems> data = (List<EntityShoppingListItems>)t;
                                adapter.setList(data);
                            }
                        });

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