android - কিভাবে অ্যান্ড্রয়েড পরিষেবা কার্যকলাপ সঙ্গে যোগাযোগ আছে




android-activity android-service (8)

অন্যান্য মন্তব্যগুলিতে উল্লেখিত অন্যান্য পদ্ধতিটি bindService () ব্যবহার করে ক্রিয়াকলাপ থেকে পরিষেবাটিতে আবদ্ধ হওয়া এবং পরিষেবা সংযোগ কলব্যাকের পরিষেবাটির একটি উদাহরণ পেতে হয়। এখানে বর্ণনা করা হয়েছে http://developer.android.com/guide/components/bound-services.html

আমি আমার প্রথম অ্যান্ড্রয়েড অ্যাপ্লিকেশন লিখছি এবং পরিষেবা এবং ক্রিয়াকলাপের মধ্যে যোগাযোগের কাছাকাছি আমার মাথা পেতে চেষ্টা করছি। আমার এমন একটি পরিষেবা রয়েছে যা ব্যাকগ্রাউন্ডে চলবে এবং কিছু GPS এবং সময় ভিত্তিক লগিং করবে। আমার এমন একটি ক্রিয়াকলাপ থাকবে যা পরিষেবাটি শুরু এবং বন্ধ করতে ব্যবহার করা হবে।

প্রথমত, আমি যখন কার্যকলাপটি শুরু হয় তখন পরিষেবাটি চলছে কিনা তা নির্ধারণ করতে সক্ষম হওয়া দরকার। এখানে অন্য কিছু প্রশ্ন আছে, তাই আমি মনে করি আমি এটি খুঁজে বের করতে পারি (তবে পরামর্শ দিতে বিনা দ্বিধায়)।

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

মনে হচ্ছে যে পরিষেবাটি চলমান কিনা তা নির্ধারণ করতে সক্ষম হওয়া উচিত এবং যদি তা হয় তবে শ্রোতা হিসাবে ক্রিয়াকলাপ যুক্ত করুন। তারপরে কার্যকলাপটি বিরাম দেয় বা বন্ধ হয়ে গেলে শ্রোতা হিসাবে ক্রিয়াকলাপটি সরান। এটা আসলে কি সম্ভব? একমাত্র উপায় আমি এটি করতে পারব এটি কার্যকলাপকে পার্সেসেবল বাস্তবায়ন করা এবং একটি এডল ফাইল তৈরি করা যাতে আমি সেটির দূরবর্তী ইন্টারফেসের মাধ্যমে এটি পাস করতে পারি। যদিও এটি ওভারকিলের মতো মনে হয়, এবং আমার কোনও ধারণা নেই যে কার্যকলাপটি কীভাবে প্রয়োগ করা উচিত। ToParcel () / readFromParcel ()।

একটি সহজ বা ভাল উপায় আছে? কোন সাহায্যের জন্য ধন্যবাদ।

সম্পাদনা করুন:

যে কেউ এই বিষয়ে আগ্রহী, তার জন্য নমুনা ডিরেক্টরিতে এইড পরিচালনা করে গুগল থেকে নমুনা কোড রয়েছে: /apis/app/RemoteService.java


আপনার অ্যাপ্লিকেশনের অভ্যন্তরে স্থানীয় পরিষেবা থেকে প্রেরিত সম্প্রচারের জন্য একটি রিসিভার নিবন্ধন করতে LocalBroadcastManager ব্যবহার করুন, রেফারেন্স এখানে LocalBroadcastManager :

developer.android.com/reference/android/support/v4/content/…


আমার পদ্ধতি:

ক্লাস পরিচালনা / পরিষেবা / কার্যকলাপ থেকে বার্তা পাঠান এবং গ্রহণ করুন:

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MessageManager {

    public interface IOnHandleMessage{
        // Messages
        int MSG_HANDSHAKE = 0x1;

        void onHandleMessage(Message msg);
    }

    private static final String LOGCAT = MessageManager.class.getSimpleName();

    private Messenger mMsgSender;
    private Messenger mMsgReceiver;
    private List<Message> mMessages;

    public MessageManager(IOnHandleMessage callback, IBinder target){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_ACTIVITY));
        mMsgSender = new Messenger(target);
        mMessages = new ArrayList<>();
    }

    public MessageManager(IOnHandleMessage callback){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_SERVICE));
        mMsgSender = null;
        mMessages = new ArrayList<>();
    }

    /* START Getter & Setter Methods */
    public Messenger getMsgSender() {
        return mMsgSender;
    }

    public void setMsgSender(Messenger sender) {
        this.mMsgSender = sender;
    }

    public Messenger getMsgReceiver() {
        return mMsgReceiver;
    }

    public void setMsgReceiver(Messenger receiver) {
        this.mMsgReceiver = receiver;
    }

    public List<Message> getLastMessages() {
        return mMessages;
    }

    public void addMessage(Message message) {
        this.mMessages.add(message);
    }
    /* END Getter & Setter Methods */

    /* START Public Methods */
    public void sendMessage(int what, int arg1, int arg2, Bundle msgData){
        if(mMsgSender != null && mMsgReceiver != null) {
            try {
                Message msg = Message.obtain(null, what, arg1, arg2);
                msg.replyTo = mMsgReceiver;
                if(msgData != null){
                    msg.setData(msgData);
                }
                mMsgSender.send(msg);
            } catch (RemoteException rE) {
                onException(rE);
            }
        }
    }

    public void sendHandshake(){
        if(mMsgSender != null && mMsgReceiver != null){
            sendMessage(IOnHandleMessage.MSG_HANDSHAKE, 0, 0, null);
        }
    }
    /* END Public Methods */

    /* START Private Methods */
    private void onException(Exception e){
        Log.e(LOGCAT, e.getMessage());
        e.printStackTrace();
    }
    /* END Private Methods */

    /** START Private Classes **/
    private class MessageHandler extends Handler {

        // Types
        final static int TYPE_SERVICE = 0x1;
        final static int TYPE_ACTIVITY = 0x2;

        private IOnHandleMessage mCallback;
        private int mType;

        public MessageHandler(IOnHandleMessage callback, int type){
            mCallback = callback;
            mType = type;
        }

        @Override
        public void handleMessage(Message msg){
            addMessage(msg);
            switch(msg.what){
                case IOnHandleMessage.MSG_HANDSHAKE:
                    switch(mType){
                        case TYPE_SERVICE:
                            setMsgSender(msg.replyTo);
                            sendHandshake();
                            break;
                        case TYPE_ACTIVITY:
                            Log.v(LOGCAT, "HERE");
                            break;
                    }
                    break;
                default:
                    if(mCallback != null){
                        mCallback.onHandleMessage(msg);
                    }
                    break;
            }
        }

    }
    /** END Private Classes **/

}

কার্যকলাপে উদাহরণ:

public class activity extends AppCompatActivity
      implements     ServiceConnection,
                     MessageManager.IOnHandleMessage { 

    [....]

    private MessageManager mMessenger;

    private void initMyMessenger(IBinder iBinder){
        mMessenger = new MessageManager(this, iBinder);
        mMessenger.sendHandshake();
    }

    private void bindToService(){
        Intent intent = new Intent(this, TagScanService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        /* START THE SERVICE IF NEEDED */
    }

    private void unbindToService(){
    /* UNBIND when you want (onDestroy, after operation...)
        if(mBound) {
            unbindService(mServiceConnection);
            mBound = false;
        }
    }

    /* START Override MessageManager.IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
        switch(msg.what){
            case Constants.MSG_SYNC_PROGRESS:
                Bundle data = msg.getData();
                String text = data.getString(Constants.KEY_MSG_TEXT);
                setMessageProgress(text);
                break;
            case Constants.MSG_START_SYNC:
                onStartSync();
                break;
            case Constants.MSG_END_SYNC:
                onEndSync(msg.arg1 == Constants.ARG1_SUCCESS);
                mBound = false;
                break;
        }
    }
    /* END Override MessageManager.IOnHandleMessage Methods */

    /** START Override ServiceConnection Methods **/
    private class BLEScanServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            initMyMessenger(iBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mMessenger = null;
            mBound = false;
        }
    }
    /** END Override ServiceConnection Methods **/

পরিষেবা উদাহরণে:

public class Blablabla extends Service
    implements     MessageManager.IOnHandleMessage {

    [...]

    private MessageManager mMessenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        initMessageManager();
        return mMessenger.getMsgReceiver().getBinder();
    }

    private void initMessageManager(){
        mMessenger = new MessageManager(this);
    }

    /* START Override IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
    /* Do what you want when u get a message looking the "what" attribute */
    }
    /* END Override IOnHandleMessage Methods */

ক্রিয়াকলাপ / পরিষেবা থেকে একটি বার্তা পাঠান:

mMessenger.sendMessage(what, arg1, arg2, dataBundle);

কিভাবে এটি কাজ করে:

আপনি কার্যকলাপ শুরু বা বাঁধাই কার্যকলাপ। পরিষেবাটি "অনবিন্ড" পদ্ধতিগুলি তার বার্তা মঞ্জুরকারীকে, "পরিষেবা সংযোগ" ইন্টারফেস পদ্ধতি বাস্তবায়নের মাধ্যমে ক্রিয়াকলাপে "অনসেয়ার সংযোগযুক্ত" প্রয়োগের মাধ্যমে বাইন্ডারটি ফেরত দেয়, আপনি এই আইবিন্ডারটি পান এবং আপনাকে এটি ব্যবহার করে বার্তা মঞ্জুরকারীকে ইনিট করে। কার্যকলাপের পরে তার বার্তা মেসেজ ম্যানেজার হ্যান্ডলার মেসেঞ্জারকে পরিষেবাটিতে প্রেরণ এবং হ্যান্ডশেক করতে বাধ্য করে যাতে সে তার "ম্যাসেজহ্যান্ডলার" প্রেরক (বার্তা মেনজারে "ব্যক্তিগত মেসেঞ্জার mMsgSender;") সেট করতে পারে। এই কাজটি সে জানে যে তার বার্তা কে পাঠাবে।

আপনি বার্তা মঞ্জুরকারীর একটি তালিকা / মেসেঞ্জার "প্রেরক" তালিকা ব্যবহার করেও এটি বাস্তবায়ন করতে পারেন যাতে আপনি বিভিন্ন ক্রিয়াকলাপ / পরিষেবাদিতে একাধিক বার্তা পাঠাতে পারেন অথবা আপনি বার্তা মঞ্জুরকারীর একটি বার্তা / সারি "রিসিভার" ব্যবহার করতে পারেন যাতে আপনি একাধিক পেতে পারেন বিভিন্ন ক্রিয়াকলাপ / সেবা থেকে বার্তা।

"MessageManager" উদাহরণে আপনার কাছে প্রাপ্ত সমস্ত বার্তাগুলির একটি তালিকা রয়েছে।

আপনি যদি "বার্তা মেসেঞ্জার" উদাহরণটি ব্যবহার করে "ক্রিয়াকলাপের মেসেঞ্জার" এবং "পরিষেবা মেসেঞ্জার" এর মধ্যে সংযোগটি স্বয়ংক্রিয়ভাবে দেখতে পান তবে এটি "অনসেয়ার সংযোগযুক্ত" পদ্ধতির মাধ্যমে এবং "হ্যান্ডশেক" ব্যবহারের মাধ্যমে করা হয়।

এই আপনার জন্য সহায়ক আশা করি :) আপনাকে অনেক ধন্যবাদ! বিদায়: ডি


আমি বিস্মিত যে কেউ অটো ইভেন্ট বাস লাইব্রেরির রেফারেন্স দিয়েছে

http://square.github.io/otto/

আমি আমার অ্যান্ড্রয়েড অ্যাপস এ এটি ব্যবহার করা হয়েছে এবং এটি অবিচ্ছিন্ন কাজ করে।


একটি কোড উদাহরণ দিয়ে @ এমআরএনউফ্লেক উত্তরটি অনুসরণ করতে। এই XABBER এখন ওপেন সোর্স Application ক্লাসApplication ক্লাস শোনা এবং সমন্বয়কারী শোনো এবং ম্যানেজার ইন্টারফেস এবং আরও অনেক কিছু। সব ধরণের পরিচালকদের গতিশীলভাবে লোড হয়। Xabber মধ্যে Activity´s শুরু হবে তারা Listener কি ধরনের রিপোর্ট হবে। এবং যখন কোনও Service শুরু হয় তখন এটি Application ক্লাসে শুরু হওয়া হিসাবে শুরু হয়। এখন একটি Activity একটি বার্তা পাঠানোর জন্য আপনাকে যা করতে হবে তা আপনার Activity কীভাবে প্রয়োজন তা listener জন্য তৈরি করা হয়। OnStart() OnPause() নিবন্ধন / অনিয়ম। এই Service শুধুমাত্র সেই listener সাথে কথা বলার জন্য Application শ্রেণিকে জিজ্ঞাসা করতে পারে এবং যদি সেখানে থাকে তবে কার্যকলাপটি গ্রহণ করার জন্য প্রস্তুত।

Application ক্লাসের মাধ্যমে আপনি দেখতে পাবেন এখানে আরও একটি লুট আছে।


কোনও পরিষেবা এবং ক্রিয়াকলাপের মধ্যে যোগাযোগ করার জন্য একটি মেসেঞ্জার ব্যবহার করা আরেকটি সহজ উপায়।

কার্যকলাপে, সংশ্লিষ্ট মেসেঞ্জারের সাথে হ্যান্ডলার তৈরি করুন। এটি আপনার পরিষেবা থেকে বার্তা হ্যান্ডেল করবে।

class ResponseHandler extends Handler {
    @Override public void handleMessage(Message message) {
            Toast.makeText(this, "message from service",
                    Toast.LENGTH_SHORT).show();
    }
}
Messenger messenger = new Messenger(new ResponseHandler());

মেসেঞ্জারকে এটি একটি বার্তাতে সংযুক্ত করে পরিষেবাটিতে প্রেরণ করা যেতে পারে:

Message message = Message.obtain(null, MyService.ADD_RESPONSE_HANDLER);
message.replyTo = messenger;
try {
    myService.send(message);
catch (RemoteException e) {
    e.printStackTrace();
}

একটি সম্পূর্ণ উদাহরণ API ডেমোতে পাওয়া যাবে: MessengerService এবং MessengerServiceActivity । MyService কিভাবে কাজ করে তার জন্য পুরো উদাহরণটি পড়ুন।


পরিষেবাগুলির সাথে যোগাযোগ করার জন্য তিনটি সুস্পষ্ট উপায় রয়েছে:

  1. ইন্টেন্ট ব্যবহার করে
  2. এডল ব্যবহার করে
  3. পরিষেবা বস্তুটি ব্যবহার করে (একক্টন হিসাবে)

আপনার ক্ষেত্রে, আমি বিকল্প 3 দিয়ে যাব। সেটি যে পরিষেবাটি স্ব স্ব সেটি এবং এটি তৈরি করতে ক্রিয়েটিভ রেফারেন্স তৈরি করুন ():

void onCreate(Intent i) {
  sInstance = this;
}

একটি স্ট্যাটিক ফাংশন MyService getInstance() , যা স্ট্যাটিক sInstance

তারপরে Activity.onCreate() আপনি পরিষেবাটি শুরু করেন, যতক্ষণ না পরিষেবাটি আসলে শুরু হয় ততক্ষণ অকালক্রমে অপেক্ষা করুন (আপনি আপনার পরিষেবাটি আপনার অ্যাপ্লিকেশনটিকে কার্যকলাপে একটি উদ্দেশ্য প্রেরণ করে এটি প্রস্তুত করতে পারেন।) এবং তার উদাহরণটি পেতে পারেন। যখন আপনার দৃষ্টান্ত থাকে, আপনার পরিষেবাদি শ্রোতা অবজেক্টটি আপনার পরিষেবাতে নিবন্ধন করুন এবং আপনি সেট করুন। দ্রষ্টব্য: ক্রিয়াকলাপের ভিতরে মতামতগুলি সম্পাদনা করার সময় আপনাকে UI থ্রেডে তাদের সংশোধন করতে হবে, পরিষেবা সম্ভবত তার নিজস্ব থ্রেড চালাবে, তাই আপনাকে Activity.runOnUiThread() কল করতে হবে।

আপনাকে যা করতে হবে তা শেষ করার জন্য Activity.onPause() আপনার শ্রোতা বস্তুর রেফারেন্সটি সরাতে হয়, অন্যথায় আপনার কার্যকলাপের প্রসঙ্গের একটি দৃষ্টান্ত ভাল হবে না।

দ্রষ্টব্য: এই পদ্ধতিটি শুধুমাত্র তখনই দরকারী যখন আপনার অ্যাপ্লিকেশন / ক্রিয়াকলাপ / টাস্ক শুধুমাত্র পরিষেবা যা আপনার পরিষেবা অ্যাক্সেস করবে। এই ক্ষেত্রে যদি আপনি বিকল্প 1 বা 2 ব্যবহার করতে হবে না।


মধুরের বর্ণনা অনুযায়ী, আপনি যোগাযোগের জন্য একটি বাস ব্যবহার করতে পারেন।

বাস ব্যবহার করার ক্ষেত্রে আপনার কিছু বিকল্প রয়েছে:

অটো ইভেন্ট বাস লাইব্রেরী (আরএক্স জাভা পক্ষে বাদ দেওয়া হয়েছে)

http://square.github.io/otto/

সবুজ রোবট এর ইভেন্টস

http://greenrobot.org/eventbus/

NYBus (RxBus, RxJava ব্যবহার করে প্রয়োগ করা হয়েছে। EventBus এর অনুরূপ)

https://github.com/MindorksOpenSource/NYBus








android-service