স্থিতিশীল এআইডিএল

অ্যান্ড্রয়েড 10 স্থিতিশীল অ্যান্ড্রয়েড ইন্টারফেস ডেফিনিশন ল্যাঙ্গুয়েজ (এআইডিএল) এর জন্য সমর্থন যোগ করে, এটি এআইডিএল ইন্টারফেস দ্বারা উপলব্ধ অ্যাপ্লিকেশন প্রোগ্রাম ইন্টারফেস (এপিআই) এবং অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (এবিআই) ট্র্যাক রাখার একটি নতুন উপায়। স্থিতিশীল এআইডিএল ঠিক এআইডিএলের মতো কাজ করে, তবে বিল্ড সিস্টেম ইন্টারফেসের সামঞ্জস্যতা ট্র্যাক করে এবং আপনি যা করতে পারেন তার উপর বিধিনিষেধ রয়েছে:

  • বিল্ড সিস্টেমে ইন্টারফেসগুলিকে aidl_interfaces দিয়ে সংজ্ঞায়িত করা হয়।
  • ইন্টারফেসে শুধুমাত্র স্ট্রাকচার্ড ডেটা থাকতে পারে। পছন্দের প্রকারের প্রতিনিধিত্বকারী পার্সেবলগুলি স্বয়ংক্রিয়ভাবে তাদের AIDL সংজ্ঞার উপর ভিত্তি করে তৈরি করা হয় এবং স্বয়ংক্রিয়ভাবে মার্শাল করা হয় এবং অমার্জিত হয়।
  • ইন্টারফেসগুলিকে স্থিতিশীল হিসাবে ঘোষণা করা যেতে পারে (পশ্চাদগামী সামঞ্জস্যপূর্ণ)। যখন এটি ঘটে, তাদের API ট্র্যাক করা হয় এবং AIDL ইন্টারফেসের পাশে একটি ফাইলে সংস্করণ করা হয়।

কাঠামোগত বনাম স্থিতিশীল AIDL

স্ট্রাকচার্ড এআইডিএল বলতে এআইডিএল-এ বিশুদ্ধভাবে সংজ্ঞায়িত ধরনের বোঝায়। উদাহরণস্বরূপ, একটি পার্সেলযোগ্য ঘোষণা (একটি কাস্টম পার্সেলেবল) কাঠামোগত AIDL নয়। AIDL-এ সংজ্ঞায়িত ক্ষেত্র সহ পার্সেলেবলকে বলা হয় কাঠামোবদ্ধ পার্সেবল

স্থিতিশীল AIDL-এর জন্য কাঠামোগত AIDL প্রয়োজন যাতে বিল্ড সিস্টেম এবং কম্পাইলার বুঝতে পারে যে পার্সেলেবলে করা পরিবর্তনগুলি পশ্চাদমুখী সামঞ্জস্যপূর্ণ কিনা। যাইহোক, সমস্ত কাঠামোগত ইন্টারফেস স্থিতিশীল নয়। স্থিতিশীল হতে, একটি ইন্টারফেস শুধুমাত্র কাঠামোগত প্রকার ব্যবহার করতে হবে, এবং এটি নিম্নলিখিত সংস্করণ বৈশিষ্ট্যগুলিও ব্যবহার করতে হবে। বিপরীতভাবে, একটি ইন্টারফেস স্থিতিশীল নয় যদি এটি তৈরি করতে কোর বিল্ড সিস্টেম ব্যবহার করা হয় বা যদি unstable:true সেট করা হয়।

একটি AIDL ইন্টারফেস সংজ্ঞায়িত করুন

aidl_interface এর একটি সংজ্ঞা এই মত দেখায়:

aidl_interface {
    name: "my-aidl",
    srcs: ["srcs/aidl/**/*.aidl"],
    local_include_dir: "srcs/aidl",
    imports: ["other-aidl"],
    versions_with_info: [
        {
            version: "1",
            imports: ["other-aidl-V1"],
        },
        {
            version: "2",
            imports: ["other-aidl-V3"],
        }
    ],
    stability: "vintf",
    backend: {
        java: {
            enabled: true,
            platform_apis: true,
        },
        cpp: {
            enabled: true,
        },
        ndk: {
            enabled: true,
        },
        rust: {
            enabled: true,
        },
    },

}
  • name : এআইডিএল ইন্টারফেস মডিউলের নাম যা একটি এআইডিএল ইন্টারফেসকে স্বতন্ত্রভাবে সনাক্ত করে।
  • srcs : AIDL সোর্স ফাইলের তালিকা যা ইন্টারফেস রচনা করে। com.acme প্যাকেজে সংজ্ঞায়িত একটি AIDL প্রকার Foo এর পাথ <base_path>/com/acme/Foo.aidl এ হওয়া উচিত, যেখানে <base_path> Android.bp যে ডিরেক্টরির সাথে সম্পর্কিত যেকোন ডিরেক্টরি হতে পারে। পূর্ববর্তী উদাহরণে, <base_path> হল srcs/aidl
  • local_include_dir : যে পথ থেকে প্যাকেজের নাম শুরু হয়। এটি উপরে ব্যাখ্যা করা <base_path> এর সাথে মিলে যায়।
  • imports : aidl_interface মডিউলগুলির একটি তালিকা যা এটি ব্যবহার করে। যদি আপনার AIDL ইন্টারফেসগুলির মধ্যে একটি ইন্টারফেস ব্যবহার করে বা অন্য aidl_interface থেকে একটি পার্সেলেবল ব্যবহার করে, তার নাম এখানে রাখুন। এটি নিজেই নাম হতে পারে, সর্বশেষ সংস্করণটি উল্লেখ করার জন্য, অথবা একটি নির্দিষ্ট সংস্করণকে উল্লেখ করার জন্য সংস্করণ প্রত্যয় (যেমন -V1 ) সহ নাম। একটি সংস্করণ নির্দিষ্ট করা Android 12 থেকে সমর্থিত
  • versions : ইন্টারফেসের পূর্ববর্তী সংস্করণগুলি যা api_dir অধীনে হিমায়িত করা হয়েছে, Android 11 থেকে শুরু করে, versions aidl_api/ name হিমায়িত করা হয়েছে। ইন্টারফেসের কোনো হিমায়িত সংস্করণ না থাকলে, এটি নির্দিষ্ট করা উচিত নয়, এবং সামঞ্জস্য পরীক্ষা করা হবে না। এই ক্ষেত্রটি Android 13 এবং উচ্চতর versions_with_info দিয়ে প্রতিস্থাপিত হয়েছে।
  • versions_with_info : টিপলের তালিকা, যার প্রত্যেকটিতে একটি হিমায়িত সংস্করণের নাম এবং অন্যান্য aidl_interface মডিউলের সংস্করণ আমদানি সহ একটি তালিকা রয়েছে যা aidl_interface-এর এই সংস্করণটি আমদানি করেছে। একটি AIDL ইন্টারফেসের IFACE সংস্করণ V-এর সংজ্ঞা aidl_api/ IFACE / V এ অবস্থিত। এই ক্ষেত্রটি Android 13-এ চালু করা হয়েছিল এবং এটি সরাসরি Android.bp এ সংশোধন করার কথা নয়। *-update-api বা *-freeze-api ব্যবহার করে ক্ষেত্রটি যোগ বা আপডেট করা হয়। এছাড়াও, যখন কোনো ব্যবহারকারী *-update-api বা *-freeze-api ব্যবহার করে তখন versions ক্ষেত্রগুলি স্বয়ংক্রিয়ভাবে versions_with_info এ স্থানান্তরিত হয়।
  • stability : এই ইন্টারফেসের স্থিতিশীলতার প্রতিশ্রুতির জন্য ঐচ্ছিক পতাকা। এটি শুধুমাত্র "vintf" সমর্থন করে। stability সেট না থাকলে, বিল্ড সিস্টেম চেক করে যে ইন্টারফেসটি পশ্চাদমুখী সামঞ্জস্যপূর্ণ যদি না unstable উল্লেখ করা হয়। আনসেট হওয়া এই সংকলন প্রসঙ্গের মধ্যে স্থায়িত্ব সহ একটি ইন্টারফেসের সাথে মিলে যায় (তাই হয় সমস্ত সিস্টেম জিনিস, উদাহরণস্বরূপ, system.img এবং সম্পর্কিত পার্টিশনের জিনিস, বা সমস্ত বিক্রেতার জিনিস, উদাহরণস্বরূপ, vendor.img এবং সম্পর্কিত পার্টিশনের জিনিস)। যদি stability "vintf" তে সেট করা হয়, তাহলে এটি একটি স্থিতিশীলতার প্রতিশ্রুতির সাথে মিলে যায়: যতক্ষণ ব্যবহার করা হয় ততক্ষণ ইন্টারফেসটিকে স্থিতিশীল রাখতে হবে।
  • gen_trace : ট্রেসিং চালু বা বন্ধ করার জন্য ঐচ্ছিক পতাকা। অ্যান্ড্রয়েড 14 থেকে শুরু করে cpp এবং java ব্যাকএন্ডের জন্য ডিফল্টটি true
  • host_supported : ঐচ্ছিক পতাকা যা true সেট করা হলে উত্পন্ন লাইব্রেরিগুলি হোস্ট পরিবেশে উপলব্ধ করে।
  • unstable : ঐচ্ছিক পতাকা চিহ্নিত করতে ব্যবহৃত হয় যে এই ইন্টারফেসটি স্থিতিশীল হতে হবে না। এটি true হিসাবে সেট করা হলে, বিল্ড সিস্টেম ইন্টারফেসের জন্য API ডাম্প তৈরি করে না বা এটি আপডেট করার প্রয়োজন হয় না।
  • frozen : ঐচ্ছিক পতাকা যা true সেট করা হলে ইন্টারফেসের পূর্ববর্তী সংস্করণ থেকে ইন্টারফেসের কোনো পরিবর্তন নেই। এটি আরও বিল্ড-টাইম চেক সক্ষম করে। false সেট করা হলে এর অর্থ হল ইন্টারফেসটি বিকাশে রয়েছে এবং এতে নতুন পরিবর্তন রয়েছে তাই foo-freeze-api চালানো একটি নতুন সংস্করণ তৈরি করে এবং স্বয়ংক্রিয়ভাবে মানটিকে true পরিবর্তন করে। অ্যান্ড্রয়েড 14 এ চালু করা হয়েছে।
  • backend.<type>.enabled : এই ফ্ল্যাগগুলি প্রতিটি ব্যাকএন্ডকে টগল করে যেগুলির জন্য AIDL কম্পাইলার কোড তৈরি করে। চারটি ব্যাকএন্ড সমর্থিত: জাভা, সি++, এনডিকে এবং রাস্ট। Java, C++, এবং NDK ব্যাকএন্ড ডিফল্টরূপে সক্রিয় থাকে। এই তিনটি ব্যাকএন্ডের যেকোন একটির প্রয়োজন না হলে, এটি স্পষ্টভাবে নিষ্ক্রিয় করা প্রয়োজন। Android 15 পর্যন্ত মরিচা ডিফল্টরূপে অক্ষম থাকে।
  • backend.<type>.apex_available : APEX নামের তালিকা যার জন্য তৈরি করা স্টাব লাইব্রেরি উপলব্ধ।
  • backend.[cpp|java].gen_log
  • backend.[cpp|java].vndk.enabled ডিফল্ট false .
  • backend.[cpp|ndk].additional_shared_libraries এই পতাকাটি ndk_header এবং cpp_header সাথে উপযোগী।
  • backend.java.sdk_version : SDK-এর সংস্করণ উল্লেখ করার জন্য ঐচ্ছিক পতাকা যা জাভা স্টাব লাইব্রেরি তৈরি করা হয়েছে। ডিফল্ট হল "system_current"backend.java.platform_apis true হলে এটি সেট করা উচিত নয়।
  • backend.java.platform_apis : ঐচ্ছিক পতাকা যা true সেট করা উচিত যখন জেনারেট করা লাইব্রেরিগুলিকে SDK-এর পরিবর্তে প্ল্যাটফর্ম API-এর বিপরীতে তৈরি করতে হবে৷

সংস্করণ এবং সক্রিয় ব্যাকএন্ডগুলির প্রতিটি সংমিশ্রণের জন্য, একটি স্টাব লাইব্রেরি তৈরি করা হয়। একটি নির্দিষ্ট ব্যাকএন্ডের জন্য স্টাব লাইব্রেরির নির্দিষ্ট সংস্করণটি কীভাবে উল্লেখ করবেন, মডিউল নামকরণের নিয়ম দেখুন।

AIDL ফাইল লিখুন

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

// in a file like 'some/package/Thing.aidl'
package some.package;

parcelable SubThing {
    String a = "foo";
    int b;
}

boolean , char , float , double , byte , int , long , এবং String এর জন্য একটি ডিফল্ট সমর্থিত (কিন্তু প্রয়োজনীয় নয়)। অ্যান্ড্রয়েড 12-এ, ব্যবহারকারী-সংজ্ঞায়িত গণনার জন্য ডিফল্টগুলিও সমর্থিত। যখন একটি ডিফল্ট নির্দিষ্ট করা হয় না, একটি 0-এর মতো বা খালি মান ব্যবহার করা হয়। কোনো শূন্য গণনাকারী না থাকলেও ডিফল্ট মান ছাড়া গণনাগুলি 0-তে শুরু করা হয়।

স্টাব লাইব্রেরি ব্যবহার করুন

আপনার মডিউলে নির্ভরতা হিসাবে স্টাব লাইব্রেরিগুলি যুক্ত করার পরে, আপনি সেগুলিকে আপনার ফাইলগুলিতে অন্তর্ভুক্ত করতে পারেন। এখানে বিল্ড সিস্টেমে স্টাব লাইব্রেরির উদাহরণ রয়েছে (এছাড়াও Android.mk লিগ্যাসি মডিউল সংজ্ঞার জন্য ব্যবহার করা যেতে পারে):

cc_... {
    name: ...,
    shared_libs: ["my-module-name-cpp"],
    ...
}
# or
java_... {
    name: ...,
    // can also be shared_libs if your preference is to load a library and share
    // it among multiple users or if you only need access to constants
    static_libs: ["my-module-name-java"],
    ...
}
# or
rust_... {
    name: ...,
    rustlibs: ["my-module-name-rust"],
    ...
}

C++ এর উদাহরণ:

#include "some/package/IFoo.h"
#include "some/package/Thing.h"
...
    // use just like traditional AIDL

জাভাতে উদাহরণ:

import some.package.IFoo;
import some.package.Thing;
...
    // use just like traditional AIDL

মরিচা মধ্যে উদাহরণ:

use aidl_interface_name::aidl::some::package::{IFoo, Thing};
...
    // use just like traditional AIDL

সংস্করণ ইন্টারফেস

foo নামের একটি মডিউল ঘোষণা করা বিল্ড সিস্টেমে একটি লক্ষ্য তৈরি করে যা আপনি মডিউলের API পরিচালনা করতে ব্যবহার করতে পারেন। তৈরি করা হলে, foo-freeze-api অ্যান্ড্রয়েড সংস্করণের উপর নির্ভর করে api_dir বা aidl_api/ name অধীনে একটি নতুন API সংজ্ঞা যোগ করে এবং একটি .hash ফাইল যোগ করে, উভয়ই ইন্টারফেসের নতুন হিমায়িত সংস্করণের প্রতিনিধিত্ব করে। foo-freeze-api সংস্করণের জন্য অতিরিক্ত সংস্করণ এবং imports প্রতিফলিত করতে versions_with_info বৈশিষ্ট্য আপডেট করে। মূলত, versions_with_infoimports imports ক্ষেত্র থেকে অনুলিপি করা হয়। কিন্তু সর্বশেষ স্থিতিশীল সংস্করণটি আমদানির জন্য versions_with_infoimports উল্লেখ করা হয়েছে, যার কোনো স্পষ্ট সংস্করণ নেই। versions_with_info প্রপার্টি নির্দিষ্ট করার পর, বিল্ড সিস্টেম হিমায়িত সংস্করণ এবং টপ অফ ট্রি (ToT) এবং সর্বশেষ হিমায়িত সংস্করণের মধ্যে সামঞ্জস্যতা পরীক্ষা চালায়।

উপরন্তু, আপনাকে ToT সংস্করণের API সংজ্ঞা পরিচালনা করতে হবে। যখনই একটি API আপডেট করা হয়, aidl_api/ name /current আপডেট করতে foo-update-api চালান যাতে ToT সংস্করণের API সংজ্ঞা রয়েছে।

একটি ইন্টারফেসের স্থিতিশীলতা বজায় রাখতে, মালিকরা নতুন যোগ করতে পারেন:

  • একটি ইন্টারফেসের শেষের পদ্ধতি (বা স্পষ্টভাবে সংজ্ঞায়িত নতুন সিরিয়াল সহ পদ্ধতি)
  • একটি পার্সেলেবলের শেষে উপাদান (প্রতিটি উপাদানের জন্য একটি ডিফল্ট যোগ করা প্রয়োজন)
  • ধ্রুবক মান
  • অ্যান্ড্রয়েড 11-এ, গণনাকারী
  • Android 12-এ, একটি ইউনিয়নের শেষ পর্যন্ত ক্ষেত্র

অন্য কোন কর্মের অনুমতি নেই, এবং অন্য কেউ একটি ইন্টারফেস পরিবর্তন করতে পারে না (অন্যথায় তারা মালিকের পরিবর্তনের সাথে সংঘর্ষের ঝুঁকি রাখে)।

সমস্ত ইন্টারফেস মুক্তির জন্য হিমায়িত করা হয়েছে তা পরীক্ষা করতে, আপনি নিম্নলিখিত পরিবেশগত ভেরিয়েবল সেট দিয়ে তৈরি করতে পারেন:

  • AIDL_FROZEN_REL=true m ... - বিল্ডের জন্য সমস্ত স্থিতিশীল AIDL ইন্টারফেস হিমায়িত করা প্রয়োজন যার owner: ক্ষেত্র নির্দিষ্ট করা আছে।
  • AIDL_FROZEN_OWNERS="aosp test" - বিল্ডের জন্য owner: ক্ষেত্র "aosp" বা "পরীক্ষা" হিসাবে নির্দিষ্ট করা হয়েছে৷

আমদানির স্থিতিশীলতা

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

অ্যান্ড্রয়েড প্ল্যাটফর্ম কোডে android.hardware.graphics.common এই ধরনের সংস্করণ আপগ্রেডের সবচেয়ে বড় উদাহরণ।

সংস্করণযুক্ত ইন্টারফেস ব্যবহার করুন

ইন্টারফেস পদ্ধতি

রানটাইমে, একটি পুরানো সার্ভারে নতুন পদ্ধতি কল করার চেষ্টা করার সময়, নতুন ক্লায়েন্টরা ব্যাকএন্ডের উপর নির্ভর করে একটি ত্রুটি বা একটি ব্যতিক্রম পায়।

  • cpp ব্যাকএন্ড পেয়েছে ::android::UNKNOWN_TRANSACTION
  • ndk ব্যাকএন্ড STATUS_UNKNOWN_TRANSACTION পায়।
  • java ব্যাকএন্ড android.os.RemoteException পায় একটি বার্তা সহ যে API প্রয়োগ করা হয়নি।

এটি পরিচালনা করার কৌশলগুলির জন্য অনুসন্ধান সংস্করণ এবং ডিফল্ট ব্যবহার করা দেখুন।

পার্সেবল

যখন নতুন ক্ষেত্রগুলি পার্সেলেবলগুলিতে যোগ করা হয়, পুরানো ক্লায়েন্ট এবং সার্ভারগুলি সেগুলি ফেলে দেয়। যখন নতুন ক্লায়েন্ট এবং সার্ভারগুলি পুরানো পার্সেলেবলগুলি গ্রহণ করে, তখন নতুন ক্ষেত্রগুলির জন্য ডিফল্ট মানগুলি স্বয়ংক্রিয়ভাবে পূরণ করা হয়৷ এর মানে হল একটি পার্সেবলের সমস্ত নতুন ক্ষেত্রের জন্য ডিফল্টগুলি নির্দিষ্ট করা প্রয়োজন৷

ক্লায়েন্টদের আশা করা উচিত নয় যে সার্ভারগুলি নতুন ক্ষেত্রগুলি ব্যবহার করবে যদি না তারা জানে যে সার্ভারটি ক্ষেত্রটি সংজ্ঞায়িত সংস্করণটি বাস্তবায়ন করছে ( কোয়েরি সংস্করণগুলি দেখুন)৷

এনাম এবং ধ্রুবক

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

ইউনিয়ন

একটি নতুন ক্ষেত্রের সাথে একটি ইউনিয়ন পাঠানোর চেষ্টা ব্যর্থ হয় যদি রিসিভার পুরানো হয় এবং ক্ষেত্র সম্পর্কে না জানে। বাস্তবায়ন নতুন ক্ষেত্রের সাথে মিলন দেখতে হবে না. ব্যর্থতা উপেক্ষা করা হয় যদি এটি একটি একমুখী লেনদেন হয়; অন্যথায় ত্রুটিটি BAD_VALUE (C++ বা NDK ব্যাকএন্ডের জন্য) বা IllegalArgumentException (জাভা ব্যাকএন্ডের জন্য)। যদি ক্লায়েন্ট একটি পুরানো সার্ভারে নতুন ফিল্ডে একটি ইউনিয়ন সেট পাঠায়, অথবা যখন এটি একটি পুরানো ক্লায়েন্ট একটি নতুন সার্ভার থেকে ইউনিয়ন গ্রহণ করে তখন ত্রুটিটি পাওয়া যায়।

একাধিক সংস্করণ পরিচালনা করুন

Android-এ একটি লিঙ্কার নামস্থানে একটি নির্দিষ্ট aidl ইন্টারফেসের মাত্র 1টি সংস্করণ থাকতে পারে এমন পরিস্থিতি এড়াতে যেখানে তৈরি করা aidl প্রকারের একাধিক সংজ্ঞা রয়েছে। C++ এর একটি সংজ্ঞার নিয়ম রয়েছে যার জন্য প্রতিটি প্রতীকের শুধুমাত্র একটি সংজ্ঞা প্রয়োজন।

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

যদি ইন্টারফেস লাইব্রেরিটি বিভিন্ন মডিউল দ্বারা ব্যবহার করা হয়, তাহলে এটি cc_defaults , java_defaults , এবং rust_defaults তৈরি করতে সহায়ক হতে পারে যেকোন লাইব্রেরি এবং প্রসেসের যেকোন গোষ্ঠীর জন্য একই সংস্করণ ব্যবহার করতে হবে। ইন্টারফেসের একটি নতুন সংস্করণ চালু করার সময় সেই ডিফল্টগুলি আপডেট করা যেতে পারে এবং সেগুলি ব্যবহার করে সমস্ত মডিউল একসাথে আপডেট করা হয়, নিশ্চিত করে যে তারা ইন্টারফেসের বিভিন্ন সংস্করণ ব্যবহার করছে না।

cc_defaults {
  name: "my.aidl.my-process-group-ndk-shared",
  shared_libs: ["my.aidl-V3-ndk"],
  ...
}

cc_library {
  name: "foo",
  defaults: ["my.aidl.my-process-group-ndk-shared"],
  ...
}

cc_binary {
  name: "bar",
  defaults: ["my.aidl.my-process-group-ndk-shared"],
  ...
}

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

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

aidl_interface_defaults {
  name: "android.popular.common-latest-defaults",
  imports: ["android.popular.common-V3"],
  ...
}

aidl_interface {
  name: "android.foo",
  defaults: ["my.aidl.latest-ndk-shared"],
  ...
}

aidl_interface {
  name: "android.bar",
  defaults: ["my.aidl.latest-ndk-shared"],
  ...
}

পতাকা ভিত্তিক উন্নয়ন

ইন-ডেভেলপমেন্ট (আনফ্রোজেন) ইন্টারফেসগুলি রিলিজ ডিভাইসগুলিতে ব্যবহার করা যাবে না, কারণ সেগুলি পশ্চাদমুখী সামঞ্জস্যপূর্ণ হওয়ার গ্যারান্টিযুক্ত নয়৷

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

এআইডিএল নির্মাণ পতাকা

এই আচরণ নিয়ন্ত্রণকারী পতাকা হল RELEASE_AIDL_USE_UNFROZEN build/release/build_flags.bzl এ সংজ্ঞায়িত। true মানে ইন্টারফেসের আনফ্রোজেন সংস্করণটি রান টাইমে ব্যবহার করা হয় এবং false মানে হল আনফ্রোজেন সংস্করণের লাইব্রেরিগুলি তাদের শেষ হিমায়িত সংস্করণের মতো আচরণ করে। স্থানীয় বিকাশের জন্য আপনি পতাকাটিকে true ওভাররাইড করতে পারেন, তবে মুক্তির আগে অবশ্যই এটিকে false ফিরিয়ে দিতে হবে। সাধারণত ডেভেলপমেন্ট এমন একটি কনফিগারেশনের মাধ্যমে করা হয় যাতে পতাকাটি true সেট করা থাকে।

সামঞ্জস্যতা ম্যাট্রিক্স এবং ম্যানিফেস্ট

ভেন্ডর ইন্টারফেস অবজেক্ট (VINTF অবজেক্ট) নির্ধারণ করে যে কোন সংস্করণগুলি প্রত্যাশিত, এবং বিক্রেতা ইন্টারফেসের উভয় পাশে কোন সংস্করণগুলি প্রদান করা হয়।

বেশিরভাগ নন-কাটলফিশ ডিভাইসগুলি ইন্টারফেসগুলি হিমায়িত হওয়ার পরেই সাম্প্রতিক সামঞ্জস্যপূর্ণ ম্যাট্রিক্সকে লক্ষ্য করে, তাই RELEASE_AIDL_USE_UNFROZEN উপর ভিত্তি করে AIDL লাইব্রেরিতে কোনও পার্থক্য নেই।

ম্যাট্রিক্স

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

উদাহরণস্বরূপ, একটি আনফ্রোজেন সংস্করণ 4 যোগ করার সময়, <version>3-4</version> ব্যবহার করুন।

যখন সংস্করণ 4 হিমশীতল হয় আপনি সামঞ্জস্যতা ম্যাট্রিক্স থেকে সংস্করণ 3 অপসারণ করতে পারেন কারণ হিমায়িত সংস্করণ 4 ব্যবহার করা হয় যখন RELEASE_AIDL_USE_UNFROZEN false থাকে।

প্রকাশ করে

অ্যান্ড্রয়েড 15-এ, RELEASE_AIDL_USE_UNFROZEN এর মানের উপর ভিত্তি করে বিল্ড টাইমে ম্যানিফেস্ট ফাইলগুলিকে সংশোধন করতে libvintf এ একটি পরিবর্তন প্রবর্তন করা হয়েছে।

ম্যানিফেস্ট এবং ম্যানিফেস্ট ফ্র্যাগমেন্টগুলি ঘোষণা করে যে একটি ইন্টারফেসের কোন সংস্করণ একটি পরিষেবা প্রয়োগ করে। একটি ইন্টারফেসের সর্বশেষ আনফ্রোজেন সংস্করণ ব্যবহার করার সময়, এই নতুন সংস্করণটিকে প্রতিফলিত করার জন্য ম্যানিফেস্টকে অবশ্যই আপডেট করতে হবে৷ যখন RELEASE_AIDL_USE_UNFROZEN=false ম্যানিফেস্ট এন্ট্রিগুলি তৈরি করা AIDL লাইব্রেরিতে পরিবর্তন প্রতিফলিত করতে libvintf দ্বারা সামঞ্জস্য করা হয়। সংস্করণটি আনফ্রোজেন সংস্করণ, N , থেকে শেষ হিমায়িত সংস্করণ N - 1 তে পরিবর্তিত হয়েছে। অতএব, ব্যবহারকারীদের তাদের প্রতিটি পরিষেবার জন্য একাধিক ম্যানিফেস্ট বা ম্যানিফেস্ট টুকরা পরিচালনা করার দরকার নেই।

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

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

HAL বাস্তবায়ন পরিবর্তন

পতাকা-ভিত্তিক বিকাশের সাথে HAL বিকাশের সবচেয়ে বড় পার্থক্য হল RELEASE_AIDL_USE_UNFROZEN false হলে কাজ করার জন্য HAL বাস্তবায়নের জন্য শেষ হিমায়িত সংস্করণের সাথে পিছিয়ে সামঞ্জস্যপূর্ণ হতে হবে। বাস্তবায়ন এবং ডিভাইস কোডে পশ্চাদপদ সামঞ্জস্য বিবেচনা করা একটি নতুন অনুশীলন। সংস্করণযুক্ত ইন্টারফেস ব্যবহার করুন দেখুন।

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

উদাহরণ: একটি ইন্টারফেসের তিনটি হিমায়িত সংস্করণ রয়েছে। ইন্টারফেসটি একটি নতুন পদ্ধতির সাথে আপডেট করা হয়েছে। নতুন সংস্করণ 4 লাইব্রেরি ব্যবহার করার জন্য ক্লায়েন্ট এবং পরিষেবা উভয়ই আপডেট করা হয়েছে। যেহেতু V4 লাইব্রেরি ইন্টারফেসের একটি আনফ্রোজেন সংস্করণের উপর ভিত্তি করে, এটি শেষ হিমায়িত সংস্করণ, সংস্করণ 3 এর মতো আচরণ করে, যখন RELEASE_AIDL_USE_UNFROZEN false হয় এবং নতুন পদ্ধতির ব্যবহারকে বাধা দেয়।

ইন্টারফেসটি হিমায়িত হয়ে গেলে, RELEASE_AIDL_USE_UNFROZEN সমস্ত মান সেই হিমায়িত সংস্করণটি ব্যবহার করে এবং পিছনের সামঞ্জস্যতা পরিচালনা করা কোডটি সরানো যেতে পারে।

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

// Get the callback along with the version of the callback
ScopedAStatus RegisterMyCallback(const std::shared_ptr<IMyCallback>& cb) override {
    mMyCallback = cb;
    // Get the version of the callback for later when we call methods on it
    auto status = mMyCallback->getInterfaceVersion(&mMyCallbackVersion);
    return status;
}

// Example of using the callback later
void NotifyCallbackLater() {
  // From the latest frozen version (V2)
  mMyCallback->foo();
  // Call this method from the unfrozen V3 only if the callback is at least V3
  if (mMyCallbackVersion >= 3) {
    mMyCallback->bar();
  }
}

বিদ্যমান প্রকারের নতুন ক্ষেত্রগুলি ( parcelable , enum , union ) RELEASE_AIDL_USE_UNFROZEN false এবং নতুন ক্ষেত্রের মানগুলি কোনও পরিষেবা প্রেরণের চেষ্টা করার সময় প্রক্রিয়া থেকে বেরিয়ে যাওয়ার সময় বাদ দেওয়া হয়।

এই আনফ্রোজেন সংস্করণে যোগ করা নতুন ধরনের ইন্টারফেসের মাধ্যমে পাঠানো বা গ্রহণ করা যাবে না।

RELEASE_AIDL_USE_UNFROZEN false হলে বাস্তবায়ন কোনো ক্লায়েন্টের কাছ থেকে নতুন পদ্ধতির জন্য কল পায় না।

তারা যে সংস্করণে প্রবর্তিত হয়েছে শুধুমাত্র সেই সংস্করণের সাথে নতুন গণনাকারী ব্যবহার করার বিষয়ে সতর্ক থাকুন, পূর্ববর্তী সংস্করণ নয়।

সাধারণত, দূরবর্তী ইন্টারফেস কোন সংস্করণটি ব্যবহার করছে তা দেখতে আপনি foo->getInterfaceVersion() ব্যবহার করেন। তবে পতাকা-ভিত্তিক সংস্করণ সমর্থন সহ, আপনি দুটি ভিন্ন সংস্করণ বাস্তবায়ন করছেন, তাই আপনি বর্তমান ইন্টারফেসের সংস্করণ পেতে চাইতে পারেন। আপনি বর্তমান বস্তুর ইন্টারফেস সংস্করণ পেয়ে এটি করতে পারেন, উদাহরণস্বরূপ, this->getInterfaceVersion() বা my_ver এর জন্য অন্যান্য পদ্ধতি। আরও তথ্যের জন্য দূরবর্তী অবজেক্টের ইন্টারফেস সংস্করণটি অনুসন্ধান করা দেখুন।

নতুন VINTF স্থিতিশীল ইন্টারফেস

যখন একটি নতুন AIDL ইন্টারফেস প্যাকেজ যোগ করা হয় তখন শেষ হিমায়িত সংস্করণ থাকে না, তাই RELEASE_AIDL_USE_UNFROZEN false হলে ফিরে আসার কোনো আচরণ নেই। এই ইন্টারফেস ব্যবহার করবেন না. যখন RELEASE_AIDL_USE_UNFROZEN false হয়, পরিষেবা পরিচালক পরিষেবাটি ইন্টারফেসটি নিবন্ধ করার অনুমতি দেয় না এবং ক্লায়েন্টরা এটি খুঁজে পাবে না।

আপনি ডিভাইস মেকফাইলে RELEASE_AIDL_USE_UNFROZEN পতাকাটির মানের ভিত্তিতে শর্তসাপেক্ষে পরিষেবাগুলি যুক্ত করতে পারেন:

ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
PRODUCT_PACKAGES += \
    android.hardware.health.storage-service
endif

যদি পরিষেবাটি একটি বৃহত্তর প্রক্রিয়ার একটি অংশ হয় যাতে আপনি শর্তসাপেক্ষে এটিকে ডিভাইসে যোগ করতে না পারেন, আপনি IServiceManager::isDeclared() দিয়ে পরিষেবাটি ঘোষণা করা হয়েছে কিনা তা দেখতে পারেন। যদি এটি ঘোষণা করা হয় এবং নিবন্ধন করতে ব্যর্থ হয়, তাহলে প্রক্রিয়াটি বাতিল করুন। যদি এটি ঘোষণা না করা হয়, তাহলে এটি নিবন্ধন করতে ব্যর্থ হবে বলে আশা করা হচ্ছে।

একটি উন্নয়ন হাতিয়ার হিসাবে Cuttlefish

প্রতি বছর VINTF হিমায়িত হওয়ার পরে আমরা ফ্রেমওয়ার্ক সামঞ্জস্যতা ম্যাট্রিক্স (FCM) target-level এবং Cuttlefish-এর PRODUCT_SHIPPING_API_LEVEL সমন্বয় করি যাতে তারা পরের বছরের রিলিজের সাথে লঞ্চ হওয়া ডিভাইসগুলিকে প্রতিফলিত করে৷ আমরা target-level এবং PRODUCT_SHIPPING_API_LEVEL সামঞ্জস্য করি যাতে কিছু লঞ্চিং ডিভাইস আছে যা পরীক্ষিত এবং পরবর্তী বছরের রিলিজের জন্য নতুন প্রয়োজনীয়তা পূরণ করে।

যখন RELEASE_AIDL_USE_UNFROZEN true হয়, তখন ভবিষ্যতের Android রিলিজগুলির বিকাশের জন্য Cuttlefish ব্যবহার করা হয়৷ এটি পরের বছরের অ্যান্ড্রয়েড রিলিজের এফসিএম স্তর এবং PRODUCT_SHIPPING_API_LEVEL লক্ষ্য করে, পরবর্তী রিলিজের বিক্রেতার সফ্টওয়্যার প্রয়োজনীয়তা (ভিএসআর) সন্তুষ্ট করার জন্য এটি প্রয়োজন।

যখন RELEASE_AIDL_USE_UNFROZEN false হয়, তখন কাটলফিশের পূর্ববর্তী target-level থাকে এবং একটি রিলিজ ডিভাইস প্রতিফলিত করার জন্য PRODUCT_SHIPPING_API_LEVEL ৷ অ্যান্ড্রয়েড ১৪ এবং তার চেয়ে কম সময়ে, এই পার্থক্যটি বিভিন্ন গিট শাখাগুলির সাথে সম্পন্ন হবে যা এফসিএম target-level , শিপিং এপিআই স্তর বা পরবর্তী কোনও কোডকে লক্ষ্য করে অন্য কোনও কোডে পরিবর্তন আনবে না।

মডিউল নামকরণের নিয়ম

অ্যান্ড্রয়েড 11-এ, প্রতিটি সংস্করণের সংমিশ্রণ এবং ব্যাকএন্ড সক্রিয় করার জন্য, একটি স্টাব লাইব্রেরি মডিউল স্বয়ংক্রিয়ভাবে তৈরি হয়। লিঙ্ক করার জন্য একটি নির্দিষ্ট স্টাব লাইব্রেরি মডিউল উল্লেখ করতে, aidl_interface মডিউলের নাম ব্যবহার করবেন না, তবে স্টাব লাইব্রেরি মডিউলের নাম, যা ifacename - version - backend , যেখানে

  • ifacename : aidl_interface মডিউলের নাম
  • version হয়
    • হিমায়িত সংস্করণের জন্য V version-number
    • V latest-frozen-version-number + 1 টিপ-অফ-ট্রির (এখনও হিমায়িত হওয়া) সংস্করণের জন্য
  • backend হয়
    • জাভা ব্যাকএন্ডের জন্য java ,
    • সি ++ ব্যাকএন্ডের জন্য cpp ,
    • NDK ব্যাকএন্ডের জন্য ndk বা ndk_platform । আগেরটি অ্যাপের জন্য, এবং পরেরটি Android 13 পর্যন্ত প্ল্যাটফর্ম ব্যবহারের জন্য। Android 13 এবং পরবর্তীতে, শুধুমাত্র ndk ব্যবহার করুন।
    • মরিচা ব্যাকএন্ড জন্য rust

অনুমান করুন যে foo নামের একটি মডিউল রয়েছে এবং এর সর্বশেষ সংস্করণ হল 2 , এবং এটি NDK এবং C++ উভয়কেই সমর্থন করে। এই ক্ষেত্রে, AIDL এই মডিউলগুলি তৈরি করে:

  • সংস্করণ 1 উপর ভিত্তি করে
    • foo-V1-(java|cpp|ndk|ndk_platform|rust)
  • সংস্করণ 2 এর উপর ভিত্তি করে (সর্বশেষ স্থিতিশীল সংস্করণ)
    • foo-V2-(java|cpp|ndk|ndk_platform|rust)
  • টোট সংস্করণ ভিত্তিক
    • foo-V3-(java|cpp|ndk|ndk_platform|rust)

অ্যান্ড্রয়েড 11 এর তুলনায়:

  • foo- backend , যা সর্বশেষ স্থিতিশীল সংস্করণে উল্লেখ করা হয় foo- V2 - backend
  • foo-unstable- backend , যা ToT সংস্করণে উল্লেখ করা হয় foo- V3 - backend

আউটপুট ফাইলের নামগুলি সর্বদা মডিউল নামের মতোই হয়।

  • সংস্করণ 1 এর উপর ভিত্তি করে: foo-V1-(cpp|ndk|ndk_platform|rust).so
  • সংস্করণ 2 এর উপর ভিত্তি করে: foo-V2-(cpp|ndk|ndk_platform|rust).so
  • ToT সংস্করণের উপর ভিত্তি করে: foo-V3-(cpp|ndk|ndk_platform|rust).so

মনে রাখবেন যে AIDL কম্পাইলার একটি unstable সংস্করণ মডিউল তৈরি করে না বা একটি স্থিতিশীল AIDL ইন্টারফেসের জন্য একটি অ-সংস্করণ মডিউল তৈরি করে না। Android 12-এর হিসাবে, একটি স্থিতিশীল AIDL ইন্টারফেস থেকে তৈরি মডিউল নাম সর্বদা এর সংস্করণ অন্তর্ভুক্ত করে।

নতুন মেটা ইন্টারফেস পদ্ধতি

Android 10 স্থিতিশীল AIDL-এর জন্য বেশ কয়েকটি মেটা ইন্টারফেস পদ্ধতি যোগ করে।

রিমোট অবজেক্টের ইন্টারফেস সংস্করণ জিজ্ঞাসা করুন

ক্লায়েন্টরা রিমোট অবজেক্টটি প্রয়োগ করা ইন্টারফেসের সংস্করণ এবং হ্যাশ অনুসন্ধান করতে পারে এবং ক্লায়েন্ট ব্যবহার করা ইন্টারফেসের মানগুলির সাথে প্রত্যাবর্তিত মানগুলির তুলনা করতে পারে।

cpp ব্যাকএন্ড সহ উদাহরণ:

sp<IFoo> foo = ... // the remote object
int32_t my_ver = IFoo::VERSION;
int32_t remote_ver = foo->getInterfaceVersion();
if (remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::HASH;
std::string remote_hash = foo->getInterfaceHash();

ndk (এবং ndk_platform ) ব্যাকএন্ড সহ উদাহরণ:

IFoo* foo = ... // the remote object
int32_t my_ver = IFoo::version;
int32_t remote_ver = 0;
if (foo->getInterfaceVersion(&remote_ver).isOk() && remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::hash;
std::string remote_hash;
foo->getInterfaceHash(&remote_hash);

java ব্যাকএন্ড সহ উদাহরণ:

IFoo foo = ... // the remote object
int myVer = IFoo.VERSION;
int remoteVer = foo.getInterfaceVersion();
if (remoteVer < myVer) {
  // the remote side is using an older interface
}

String myHash = IFoo.HASH;
String remoteHash = foo.getInterfaceHash();

জাভা ভাষার জন্য, দূরবর্তী দিকটি অবশ্যই getInterfaceVersion() এবং getInterfaceHash() নিম্নরূপ প্রয়োগ করতে হবে ( অনুলিপি এবং পেস্টের ভুলগুলি এড়াতে IFoo পরিবর্তে super ব্যবহার করা হয়। @SuppressWarnings("static") টীকাটি সতর্কতা নিষ্ক্রিয় করার জন্য প্রয়োজন হতে পারে, এর উপর নির্ভর করে javac কনফিগারেশন):

class MyFoo extends IFoo.Stub {
    @Override
    public final int getInterfaceVersion() { return super.VERSION; }

    @Override
    public final String getInterfaceHash() { return super.HASH; }
}

কারণ জেনারেট করা ক্লাসগুলি ( IFoo , IFoo.Stub , ইত্যাদি) ক্লায়েন্ট এবং সার্ভারের মধ্যে ভাগ করা হয় (উদাহরণস্বরূপ, ক্লাসগুলি বুট ক্লাসপথে হতে পারে)। যখন ক্লাসগুলি ভাগ করা হয়, সার্ভারটি ক্লাসের নতুন সংস্করণের সাথেও লিঙ্ক করা হয় যদিও এটি ইন্টারফেসের একটি পুরানো সংস্করণ দিয়ে তৈরি করা হতে পারে। যদি এই মেটা ইন্টারফেসটি ভাগ করা ক্লাসে প্রয়োগ করা হয় তবে এটি সর্বদা নতুন সংস্করণ প্রদান করে। যাইহোক, উপরের পদ্ধতিটি প্রয়োগ করে, ইন্টারফেসের সংস্করণ নম্বরটি সার্ভারের কোডে এম্বেড করা হয়েছে (কারণ IFoo.VERSION হল একটি static final int যা রেফারেন্স করার সময় ইনলাইন করা হয়) এবং এইভাবে পদ্ধতিটি সার্ভারটি তৈরি করা সঠিক সংস্করণটি ফিরিয়ে দিতে পারে। সঙ্গে

পুরানো ইন্টারফেসের সাথে ডিল করুন

এটা সম্ভব যে একটি ক্লায়েন্ট একটি AIDL ইন্টারফেসের নতুন সংস্করণের সাথে আপডেট করা হয়েছে কিন্তু সার্ভারটি পুরানো AIDL ইন্টারফেস ব্যবহার করছে। এই জাতীয় ক্ষেত্রে, একটি পুরানো ইন্টারফেসে একটি পদ্ধতিতে কল করা UNKNOWN_TRANSACTION ফিরে আসে।

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

Android 13 এবং পরবর্তীতে C++ এর উদাহরণ:

class MyDefault : public IFooDefault {
  Status anAddedMethod(...) {
   // do something default
  }
};

// once per an interface in a process
IFoo::setDefaultImpl(::android::sp<MyDefault>::make());

foo->anAddedMethod(...); // MyDefault::anAddedMethod() will be called if the
                         // remote side is not implementing it

জাভাতে উদাহরণ:

IFoo.Stub.setDefaultImpl(new IFoo.Default() {
    @Override
    public xxx anAddedMethod(...)  throws RemoteException {
        // do something default
    }
}); // once per an interface in a process

foo.anAddedMethod(...);

আপনাকে একটি AIDL ইন্টারফেসে সমস্ত পদ্ধতির ডিফল্ট বাস্তবায়ন প্রদান করতে হবে না। যে পদ্ধতিগুলি রিমোট সাইডে প্রয়োগ করার গ্যারান্টিযুক্ত (কারণ আপনি নিশ্চিত যে রিমোটটি তৈরি করা হয়েছিল যখন পদ্ধতিগুলি AIDL ইন্টারফেসের বিবরণে ছিল) ডিফল্ট impl ক্লাসে ওভাররাইড করার প্রয়োজন নেই৷

বিদ্যমান এআইডিএলকে কাঠামোগত বা স্থিতিশীল এআইডিএলে রূপান্তর করুন

আপনার যদি একটি বিদ্যমান AIDL ইন্টারফেস এবং কোড থাকে যা এটি ব্যবহার করে, ইন্টারফেসটিকে একটি স্থিতিশীল AIDL ইন্টারফেসে রূপান্তর করতে নিম্নলিখিত পদক্ষেপগুলি ব্যবহার করুন৷

  1. আপনার ইন্টারফেসের সমস্ত নির্ভরতা সনাক্ত করুন। প্রতিটি প্যাকেজের জন্য ইন্টারফেস নির্ভর করে, প্যাকেজটি স্থিতিশীল AIDL-এ সংজ্ঞায়িত কিনা তা নির্ধারণ করুন। সংজ্ঞায়িত না হলে, প্যাকেজ রূপান্তর করা আবশ্যক.

  2. আপনার ইন্টারফেসের সমস্ত পার্সেবেলগুলিকে স্থিতিশীল পার্সেলেবলগুলিতে রূপান্তর করুন (ইন্টারফেস ফাইলগুলি নিজেরাই অপরিবর্তিত থাকতে পারে)। এআইডিএল ফাইলগুলিতে সরাসরি তাদের গঠন প্রকাশ করে এটি করুন। এই নতুন ধরনের ব্যবহার করার জন্য ম্যানেজমেন্ট ক্লাস পুনরায় লিখতে হবে। আপনি একটি aidl_interface প্যাকেজ (নীচে) তৈরি করার আগে এটি করা যেতে পারে।

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