আমি একটি সহজ এবং মার্জিত পদ্ধতি পেয়েছি:
- কোন পার্সলেবল
- কোন সিরিয়ালাইজযোগ্য
- কোনও স্থির ক্ষেত্র নেই
- ইভেন্ট বাস নেই
পদ্ধতি 1
প্রথম ক্রিয়াকলাপের জন্য কোড:
final Object objSent = new Object();
final Bundle bundle = new Bundle();
bundle.putBinder("object_value", new ObjectWrapperForBinder(objSent));
startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
Log.d(TAG, "original object=" + objSent);
দ্বিতীয় ক্রিয়াকলাপের কোড:
final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
Log.d(TAG, "received object=" + objReceived);
আপনি খুঁজে পাবেন objSent
এবং objReceived
একই পাবেন hashCode
, তাই তারা অভিন্ন।
তবে কেন আমরা এইভাবে কোনও জাভা বস্তুটি পাস করতে পারি?
প্রকৃতপক্ষে, অ্যান্ড্রয়েড বাইন্ডার জাভা অবজেক্টের জন্য বিশ্বব্যাপী জেএনআই রেফারেন্স তৈরি করবে এবং এই জাভা অবজেক্টের কোনও রেফারেন্স না থাকলে এই বিশ্বব্যাপী জেএনআই রেফারেন্স প্রকাশ করবে। বাইন্ডার বাইন্ডার অবজেক্টে এই বিশ্বব্যাপী জেএনআই রেফারেন্সটি সংরক্ষণ করবে।
* সতর্কতা: এই পদ্ধতিটি কেবলমাত্র তখনই কাজ করে, যদি না দুটি কার্যক্রম একই প্রক্রিয়াতে চালিত হয়, না হলে (অবজেক্টরেপ্পারবাইন্ডার) getIntent ()। GetExtras ()। GetBinder ("অবজেক্ট_ভ্যালু") * এ ক্লাসকাস্টএক্সপশন নিক্ষেপ করুন *
বর্গ অবজেক্টরেপ্পারবাইন্ডার সংজ্ঞা
public class ObjectWrapperForBinder extends Binder {
private final Object mData;
public ObjectWrapperForBinder(Object data) {
mData = data;
}
public Object getData() {
return mData;
}
}
পদ্ধতি 2
- প্রেরকের জন্য,
- আপনার জাভা অবজেক্টটিকে জেএনআই গ্লোবাল রেফারেন্স সারণিতে যুক্ত করতে কাস্টম নেটিভ পদ্ধতিটি ব্যবহার করুন (জেএনআইএনএনভি :: নিউগ্লোবালআরফের মাধ্যমে)
- রিটার্ন পূর্ণসংখ্যা (প্রকৃতপক্ষে, জেএনআইএনভি :: নিউগ্লোবালআরফ রিটার্ন জবজেক্ট, যা একটি পয়েন্টার, আমরা এটি নিরাপদে ইন্টিতে ফেলে দিতে পারি) আপনার ইন্টেন্টে (ইনটেন্ট :: পুটেক্সট্রার মাধ্যমে)
- গ্রহীতার জন্য
- ইন্টেন্ট থেকে পূর্ণসংখ্যা পান (ইন্টেন্ট :: getInt এর মাধ্যমে)
- JNI গ্লোবাল রেফারেন্স টেবিল থেকে আপনার জাভা অবজেক্টটি পুনরুদ্ধার করতে কাস্টম নেটিভ পদ্ধতি ব্যবহার করুন (JNIEnv :: NewLocalRef এর মাধ্যমে)
- জেএনআই গ্লোবাল রেফারেন্স টেবিল থেকে আইটেমটি সরান (জেএনআইইএনভি :: মুছুন গ্লোবালআরফের মাধ্যমে),
তবে পদ্ধতি 2 এর একটি সামান্য তবে গুরুতর সমস্যা রয়েছে, যদি রিসিভার জাভা বস্তুটি পুনরুদ্ধার করতে ব্যর্থ হয় (উদাহরণস্বরূপ, জাভা বস্তু পুনরুদ্ধার করার আগে কিছু ব্যতিক্রম ঘটে, বা রিসিভার ক্রিয়াকলাপের অস্তিত্ব নেই) তবে জাভা বস্তুটি হয়ে যাবে এতিম বা মেমরি ফাঁস, পদ্ধতি 1 এ এই সমস্যাটি নেই, কারণ অ্যান্ড্রয়েড বাইন্ডার এই ব্যতিক্রমটি পরিচালনা করবে
পদ্ধতি 3
জাভা অবজেক্টকে দূর থেকে অনুরোধ করার জন্য, আমরা জাভা অবজেক্টটি বর্ণনা করার জন্য একটি ডেটা চুক্তি / ইন্টারফেস তৈরি করব, আমরা এইডিল ফাইলটি ব্যবহার করব
IDataContract.aidl
package com.example.objectwrapper;
interface IDataContract {
int func1(String arg1);
int func2(String arg1);
}
প্রথম ক্রিয়াকলাপের জন্য কোড
final IDataContract objSent = new IDataContract.Stub() {
@Override
public int func2(String arg1) throws RemoteException {
// TODO Auto-generated method stub
Log.d(TAG, "func2:: arg1=" + arg1);
return 102;
}
@Override
public int func1(String arg1) throws RemoteException {
// TODO Auto-generated method stub
Log.d(TAG, "func1:: arg1=" + arg1);
return 101;
}
};
final Bundle bundle = new Bundle();
bundle.putBinder("object_value", objSent.asBinder());
startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
Log.d(TAG, "original object=" + objSent);
দ্বিতীয় ক্রিয়াকলাপের কোড:
দ্বিতীয় ক্রিয়াকলাপ অন্য কোনও প্রক্রিয়াতে চলছে তা নিশ্চিত করার জন্য অ্যান্ড্রয়েড: প্রক্রিয়া বৈশিষ্ট্যটি অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলকে একটি খালি নয় প্রক্রিয়া নামে পরিবর্তন করুন
final IDataContract objReceived = IDataContract.Stub.asInterface(getIntent().getExtras().getBinder("object_value"));
try {
Log.d(TAG, "received object=" + objReceived + ", func1()=" + objReceived.func1("test1") + ", func2()=" + objReceived.func2("test2"));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
এই পদ্ধতিতে, আমরা দুটি ক্রিয়াকলাপের মধ্যে পৃথক প্রক্রিয়া চলাকালীন দুটি ক্রিয়াকলাপের মধ্যে একটি ইন্টারফেস পাস করতে পারি এবং ইন্টারফেস পদ্ধতিটিকে দূর থেকে কল করতে পারি
পদ্ধতি 4
পদ্ধতি 3 যথেষ্ট সহজ বলে মনে হচ্ছে না কারণ আমাদের অবশ্যই একটি সহায়তা ইন্টারফেস প্রয়োগ করতে হবে। আপনি যদি কেবল সাধারণ কাজটি করতে চান এবং পদ্ধতিটির ফেরতের মান অপ্রয়োজনীয় হয়, আমরা android.os.Mesender ব্যবহার করতে পারি
প্রথম ক্রিয়াকলাপের জন্য প্রেরক (প্রেরক):
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int MSG_OP1 = 1;
public static final int MSG_OP2 = 2;
public static final String EXTRA_MESSENGER = "messenger";
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.e(TAG, "handleMessage:: msg=" + msg);
switch (msg.what) {
case MSG_OP1:
break;
case MSG_OP2:
break;
default:
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startActivity(new Intent(this, SecondActivity.class).putExtra(EXTRA_MESSENGER, new Messenger(mHandler)));
}
}
দ্বিতীয় ক্রিয়াকলাপের জন্য কোড (রিসিভার):
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
final Messenger messenger = getIntent().getParcelableExtra(MainActivity.EXTRA_MESSENGER);
try {
messenger.send(Message.obtain(null, MainActivity.MSG_OP1, 101, 1001, "10001"));
messenger.send(Message.obtain(null, MainActivity.MSG_OP2, 102, 1002, "10002"));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
সমস্ত ম্যাসেঞ্জার.সেন্ড হ'ল হ্যান্ডলারের মধ্যে সংযোজনীয় এবং ক্রমানুসারে কার্যকর করা হবে।
আসলে, অ্যান্ড্রয়েড.ওস.ম্যাসেঞ্জার হ'ল একটি সহায়তা ইন্টারফেসও যদি আপনার অ্যান্ড্রয়েড সোর্স কোড থাকে তবে আপনি IMesender.aidl নামের একটি ফাইল খুঁজে পেতে পারেন
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
void send(in Message msg);
}