অ্যান্ড্রয়েডে ক্রিয়াকলাপের সাথে পরিষেবা বাঁধুন


90

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

আমি জানি যে আমি অনবিন্দ () ব্যবহার করে ক্রিয়াকলাপের সাথে পরিষেবাটি আবদ্ধ করতে পারি, তবে যদি আমি সঠিকভাবে বুঝতে পারি তবে যদি কার্যকলাপটি নিহত হয় তবে এটি পরিষেবাটি বন্ধ করে দেবে। ব্যবহারকারী যদি কার্যকলাপটি থেকে বেরিয়ে আসে তবেও আমি প্লেব্যাক চালিয়ে যেতে চাই। এই সমস্যাটি মোকাবেলার জন্য কি কোনও মানক বা পছন্দের উপায় আছে?

উত্তর:


154

"আপনি একটি Android পরিষেবা শুরু করেন সঙ্গে startService(..)যে পরিষেবাটি যতক্ষণ না আপনি স্পষ্টভাবে ডাকা চলমান থাকবে stopService(..)। সেখানে দুটি কারণে যে একটি সেবা সিস্টেম দ্বারা পরিচালিত করা যেতে পারে। কেউ কল তাহলে Context.startService()তারপর সিস্টেম (এটা তৈরি এবং তার কলিং সেবা পুনরুদ্ধার করবে onCreate()যদি পদ্ধতি প্রয়োজনীয়) এবং তারপরে onStartCommand(Intent, int, int)ক্লায়েন্টের সরবরাহিত আর্গুমেন্টগুলির সাথে তার পদ্ধতিটি কল করুন The পরিষেবাটি এই মুহুর্তে অবধি Context.stopService()বা না stopSelf()বলা অবধি চলতে থাকবে Note নোট করুন যে একাধিক কল Context.startService()নীড় বাড়ে না (যদিও তারা একাধিক অনুরূপ কলগুলিতে ফলাফল করে onStartCommand()), তাই না এটি একবারে কোনও পরিষেবা শুরু হয়ে গেলে Context.stopService()বা একবার stopSelf()বলা বন্ধ হয়ে যায় ; তবে পরিষেবাগুলি সেগুলি তাদের ব্যবহার করতে পারেstopSelf(int) শুরু হওয়া উদ্দেশ্যগুলি প্রক্রিয়া না করা পর্যন্ত পরিষেবাটি বন্ধ না হওয়া নিশ্চিত করার পদ্ধতি।

ক্লায়েন্টরা Context.bindService()কোনও পরিষেবায় অবিচ্ছিন্ন সংযোগ পেতে ব্যবহার করতে পারেন । এটি ইতিমধ্যে পরিষেবাটি তৈরি করে যদি এটি ইতিমধ্যে চালু না থাকে ( onCreate()এমন করার সময় কল করা ), তবে কল না করে onStartCommand()। ক্লায়েন্টটি IBinderতার onBind(Intent)পদ্ধতি থেকে পরিষেবাটি প্রত্যাখ্যান করে সেই ক্লায়েন্টটি ক্লায়েন্টকে তার পরে পরিষেবাতে কল করার অনুমতি দেবে allowing সংযোগটি প্রতিষ্ঠিত হওয়ার পরে পরিষেবাটি চলমান থাকবে (ক্লায়েন্ট পরিষেবার ক্ষেত্রে কোনও রেফারেন্স ধরে রাখুক বা না রাখুক IBinder)। সাধারণত IBinderফিরে আসাটি একটি জটিল ইন্টারফেসের জন্য যা এআইডিএলে লেখা হয়েছিল।

একটি পরিষেবা উভয়ই শুরু করা যেতে পারে এবং এর সাথে সংযোগ থাকতে পারে। এই জাতীয় ক্ষেত্রে, সিস্টেমটি যতক্ষণ না এটি শুরু হয় বা Context.BIND_AUTO_CREATEপতাকাটির সাথে এর সাথে আরও এক বা একাধিক সংযোগ রয়েছে ততক্ষণ পরিষেবাটি চালিয়ে রাখবে । একবারে এই পরিস্থিতিগুলির মধ্যে একটিও ধরে না নিলে পরিষেবাটির onDestroy()পদ্ধতিটি কল করা হয় এবং পরিষেবাটি কার্যকরভাবে বন্ধ হয়ে যায়। সমস্ত ক্লিনআপ (থ্রেড থামানো, নিবন্ধনবিহীন রিসিভারগুলি) এখান থেকে ফিরে আসার পরে সম্পূর্ণ করা উচিত onDestroy()। "


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

4
আপনি যদি স্টার্ট সার্ভিস কল করে সাধারণ সার্ভার ব্যবহার করছেন তবে আপনি স্টপসেলফ () বা স্টপ সার্ভিস () না কল করা পর্যন্ত পরিষেবা বন্ধ হবে না। এবং পরবর্তী আপনি যদি বাইড সার্ভিস ব্যবহার করেন তবে হ্যাঁ পরিষেবাটি যদি সমস্ত সংযুক্ত / বাইন্ড উপাদান নষ্ট করে তবে মারা যাবে।
আসিফ মোশতাক

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

আপনি কি দয়া করে এই প্রশ্নে আমাকে সহায়তা করতে পারেন stackoverflow.com/questions/51508046/…
রাজেশ কে

25

প্রথমত, 2 জিনিস যা আমাদের বুঝতে হবে

ক্লায়েন্ট

  • এটি নির্দিষ্ট সার্ভারে অনুরোধ করে

    bindService(new 
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

এখানে শ্রেণীর mServiceConnউদাহরণ রয়েছে ServiceConnection(ইনবিল্ট) এটি আসলে ইন্টারফেস যা আমাদের নেটওয়ার্ক সংযোগের অবস্থা পর্যবেক্ষণের জন্য দুটি (প্রথম নেটওয়ার্ক সংযুক্ত এবং দ্বিতীয় নেটওয়ার্ক সংযুক্ত নয়) পদ্ধতিতে প্রয়োগ করতে হবে।

সার্ভার

  • এটি ক্লায়েন্টের অনুরোধটি পরিচালনা করে এবং নিজস্ব নিজস্ব প্রতিরূপ তৈরি করে যা কেবলমাত্র ক্লায়েন্টের কাছে ব্যক্তিগত যারা অনুরোধ পাঠায় এবং সার্ভারের এই প্রতিলিপিটি বিভিন্ন থ্রেডে চলমান।

এখন ক্লায়েন্ট সাইডে, সার্ভারের সমস্ত পদ্ধতি অ্যাক্সেস করবেন কীভাবে?

  • সার্ভারটি আইবাইন্ড অবজেক্টের সাথে প্রতিক্রিয়া প্রেরণ করে so সুতরাং আইবিন্দ অবজেক্টটি আমাদের হ্যান্ডলার যা (।) অপারেটরটি ব্যবহার করে পরিষেবার সমস্ত পদ্ধতি অ্যাক্সেস করে।

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

এখন পরিষেবাতে থাকা পদ্ধতিটি কীভাবে কল করবেন

myservice.serviceMethod();

এখানে myServiceঅবজেক্ট এবং serviceMethodeপরিষেবাতে পদ্ধতি। এবং এইভাবে ক্লায়েন্ট এবং সার্ভারের মধ্যে যোগাযোগ স্থাপন করা হয়।


10

আমি ফোন করার চেষ্টা করেছি

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

ফলস্বরূপ এবং আমি একটি স্টিকি পরিষেবা তৈরি করতে এবং এটিতে আবদ্ধ করতে পারি। বাউন্ড সার্ভিস উদাহরণের জন্য বিশদ টিউটোরিয়াল ।


5

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

আপনি যদি আবার এটির সাথে সংযোগ স্থাপন করেন তখন এটি একটি সমস্যা তৈরি করতে পারে, যেহেতু আপনি আবার কার্যকলাপ শুরু করার সময় এটি চলমান কিনা তা সম্ভবত আপনি জানেন না, তাই আপনার ক্রিয়াকলাপে আপনার এটি বিবেচনা করতে হবে।

শুভকামনা!


-1

এটি পক্ষপাতদুষ্ট উত্তর, তবে আমি একটি লাইব্রেরি লিখেছি যা অ্যান্ড্রয়েড পরিষেবাদির ব্যবহারকে সহজতর করতে পারে, যদি তারা অ্যাপ্লিকেশনটির মতো একই প্রক্রিয়াতে স্থানীয়ভাবে চালিত হয়: https://github.com/germnix/acacia

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

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

অবিচ্ছিন্ন বিজ্ঞপ্তিগুলি আড়াল / প্রদর্শন করতে, আপনার নিজের android.app.S सर्विस ব্যবহার করতে এবং আপনি চান থ্রেডিং ম্যানুয়ালি হ্যান্ডেল করার জন্য আপনি সম্পর্কিত android.app.S सर्विसের উদাহরণ পেতে পারেন।


-5

যদি ব্যবহারকারী ব্যাক আউট করে তবে onDestroy()পদ্ধতিটি কল করা হবে। এই পদ্ধতিটি হ'ল অ্যাপ্লিকেশনটিতে ব্যবহৃত কোনও পরিষেবা বন্ধ করা। সুতরাং যদি আপনি পরিষেবাটি চালিয়ে যেতে চান এমনকি যদি ব্যবহারকারী অ্যাপ্লিকেশনটি থেকে ব্যাক করেন তবে কেবল মুছুন onDestroy()। এই সাহায্য আশা করি।


আপনার আইডিই যদি স্বয়ংক্রিয়ভাবে একটি তৈরি করে তবে আপনাকে ফাংশনটিকে ওভাররাইড করতে হবে এবং সুপারক্লাসের অনডাস্ট্রয়ে () এ ডিফল্ট কলটি মুছতে হবে। তবে আপনি কেন কখনও এটি করতে চান?
রিপটিডে 4
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.