অ্যাপ-মধ্যস্থ সামগ্রী লোড করুন

আপনি ওয়েব-ভিত্তিক সামগ্রী প্রদান করতে পারেন—যেমন HTML, JavaScript, এবং CSS—আপনার অ্যাপ ব্যবহার করার জন্য যা আপনি ইন্টারনেটে আনার পরিবর্তে অ্যাপ্লিকেশানে স্থিরভাবে কম্পাইল করেন।

অ্যাপ-মধ্যস্থ সামগ্রীর জন্য ইন্টারনেট অ্যাক্সেসের প্রয়োজন হয় না বা ব্যবহারকারীর ব্যান্ডউইথ ব্যবহার করে না। যদি বিষয়বস্তুটি শুধুমাত্র WebView এর জন্য বিশেষভাবে ডিজাইন করা হয়-অর্থাৎ, এটি একটি নেটিভ অ্যাপের সাথে যোগাযোগের উপর নির্ভর করে-তাহলে ব্যবহারকারীরা ভুলবশত এটি একটি ওয়েব ব্রাউজারে লোড করতে পারবেন না।

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

WebViewAssetLoader

WebViewAssetLoader হল একটি WebView অবজেক্টে অ্যাপ-মধ্যস্থ সামগ্রী লোড করার একটি নমনীয় এবং কার্যকরী উপায়। এই ক্লাস নিম্নলিখিত সমর্থন করে:

  • একই-অরিজিন নীতির সাথে সামঞ্জস্যের জন্য একটি HTTP(S) URL সহ সামগ্রী লোড করা হচ্ছে৷
  • জাভাস্ক্রিপ্ট, সিএসএস, ইমেজ এবং আইফ্রেমের মতো সাবরিসোর্স লোড করা হচ্ছে।

আপনার প্রধান কার্যকলাপ ফাইলে WebViewAssetLoader অন্তর্ভুক্ত করুন। নিম্নলিখিত সম্পদ ফোল্ডার থেকে সাধারণ ওয়েব সামগ্রী লোড করার একটি উদাহরণ:

কোটলিন

private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
    @RequiresApi(21)
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }

    // To support API < 21.
    override fun shouldInterceptRequest(
        view: WebView,
        url: String
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(Uri.parse(url))
    }
}

জাভা

private static class LocalContentWebViewClient extends WebViewClientCompat {

    private final WebViewAssetLoader mAssetLoader;

    LocalContentWebViewClient(WebViewAssetLoader assetLoader) {
        mAssetLoader = assetLoader;
    }

    @Override
    @RequiresApi(21)
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     WebResourceRequest request) {
        return mAssetLoader.shouldInterceptRequest(request.getUrl());
    }

    @Override
    @SuppressWarnings("deprecation") // To support API < 21.
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     String url) {
        return mAssetLoader.shouldInterceptRequest(Uri.parse(url));
    }
}

আপনার অ্যাপ্লিকেশানটিকে অবশ্যই একটি WebViewAssetLoader দৃষ্টান্ত কনফিগার করতে হবে যাতে এটির প্রয়োজন হয়৷ পরবর্তী বিভাগে একটি উদাহরণ আছে.

অ্যাপ-মধ্যস্থ সম্পদ এবং সম্পদ তৈরি করুন

WebViewAssetLoader একটি প্রদত্ত সংস্থান পথের সাথে সম্পর্কিত সংস্থানগুলি লোড করতে PathHandler দৃষ্টান্তগুলির উপর নির্ভর করে। যদিও আপনি আপনার অ্যাপের প্রয়োজন অনুযায়ী সংস্থানগুলি পুনরুদ্ধার করতে এই ইন্টারফেসটি প্রয়োগ করতে পারেন, Webkit লাইব্রেরি যথাক্রমে Android সম্পদ এবং সম্পদ লোড করার জন্য AssetsPathHandler এবং ResourcesPathHandler বান্ডেল করে৷

শুরু করতে, আপনার অ্যাপের জন্য সম্পদ এবং সংস্থান তৈরি করুন। সাধারণত, নিম্নলিখিতগুলি প্রযোজ্য:

  • এইচটিএমএল, জাভাস্ক্রিপ্ট এবং সিএসএস এর মত টেক্সট ফাইল সম্পদের অন্তর্গত।
  • ছবি এবং অন্যান্য বাইনারি ফাইল সম্পদের অন্তর্গত।

একটি প্রকল্পে পাঠ্য-ভিত্তিক ওয়েব ফাইল যুক্ত করতে, নিম্নলিখিতগুলি করুন:

  1. অ্যান্ড্রয়েড স্টুডিওতে, অ্যাপ > src > প্রধান ফোল্ডারে ডান-ক্লিক করুন এবং তারপর নতুন > ডিরেক্টরি নির্বাচন করুন।
    অ্যান্ড্রয়েড স্টুডিও তৈরি-ডিরেক্টরি মেনু দেখানো একটি চিত্র৷
    চিত্র 1. আপনার প্রকল্পের জন্য একটি সম্পদ ফোল্ডার তৈরি করুন।
  2. ফোল্ডারের নাম দিন "সম্পদ"।
    সম্পদ ফোল্ডার দেখানো একটি ছবি
    চিত্র 2. সম্পদ ফোল্ডারের নাম দিন।
  3. সম্পদ ফোল্ডারে ডান-ক্লিক করুন এবং তারপর নতুন > ফাইলে ক্লিক করুন। index.html লিখুন এবং Return বা Enter কী টিপুন।
  4. stylesheet.css এর জন্য একটি খালি ফাইল তৈরি করতে আগের ধাপটি পুনরাবৃত্তি করুন।
  5. পরবর্তী দুটি কোড নমুনায় বিষয়বস্তু দিয়ে আপনার তৈরি করা খালি ফাইলগুলি পূরণ করুন।
```html
<!-- index.html content -->

<html>
  <head>
    <!-- Tip: Use relative URLs when referring to other in-app content to give
              your app code the flexibility to change the scheme or domain as
              necessary. -->
    <link rel="stylesheet" href="/assets/stylesheet.css">
  </head>
  <body>
    <p>This file is loaded from in-app content.</p>
    <p><img src="/res/drawable/android_robot.png" alt="Android robot" width="100"></p>
  </body>
</html>
```

```css
<!-- stylesheet.css content -->

body {
  background-color: lightblue;
}
```

আপনার প্রকল্পে একটি ইমেজ-ভিত্তিক ওয়েব ফাইল যোগ করতে, নিম্নলিখিতগুলি করুন:

  1. আপনার স্থানীয় মেশিনে Android_symbol_green_RGB.png ফাইলটি ডাউনলোড করুন।

  2. ফাইলটির নাম পরিবর্তন করে android_robot.png করুন।

  3. ম্যানুয়ালি ফাইলটিকে আপনার হার্ড ড্রাইভে আপনার প্রোজেক্টের main/res/drawable ডিরেক্টরিতে সরান।

চিত্র 4 আপনার যোগ করা ছবি এবং একটি অ্যাপে রেন্ডার করা পূর্ববর্তী কোড নমুনা থেকে পাঠ্য দেখায়।

অ্যাপ রেন্ডার করা আউটপুট দেখানো একটি ছবি
চিত্র 4. ইন-অ্যাপ HTML ফাইল এবং একটি অ্যাপে রেন্ডার করা চিত্র ফাইল।

অ্যাপটি সম্পূর্ণ করতে, নিম্নলিখিতগুলি করুন:

  1. হ্যান্ডলারদের নিবন্ধন করুন এবং onCreate() পদ্ধতিতে নিম্নলিখিত কোড যোগ করে AssetLoader কনফিগার করুন:

    কোটলিন

    val assetLoader = WebViewAssetLoader.Builder()
                           .addPathHandler("/assets/", AssetsPathHandler(this))
                           .addPathHandler("/res/", ResourcesPathHandler(this))
                           .build()
    webView.webViewClient = LocalContentWebViewClient(assetLoader)

    জাভা

    final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
             .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
             .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this))
             .build();
    mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
  2. onCreate() পদ্ধতিতে নিম্নলিখিত কোড যোগ করে বিষয়বস্তু লোড করুন:

    কোটলিন

    webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")

    জাভা

    mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");

আপনার ওয়েবসাইটের সংস্থানগুলির সাথে অ্যাপ-মধ্যস্থ সামগ্রী মিশ্রিত করুন

আপনার অ্যাপটিকে অ্যাপ-মধ্যস্থ সামগ্রী এবং ইন্টারনেট থেকে সামগ্রীর মিশ্রণ লোড করতে হতে পারে, যেমন আপনার ওয়েবসাইটের CSS দ্বারা স্টাইল করা একটি ইন-অ্যাপ HTML পৃষ্ঠা। WebViewAssetLoader এই ব্যবহারের ক্ষেত্রে সমর্থন করে। যদি নিবন্ধিত PathHandler দৃষ্টান্তগুলির মধ্যে কোনটি প্রদত্ত পথের জন্য একটি সংস্থান খুঁজে না পায়, WebView ইন্টারনেট থেকে সামগ্রী লোড করতে ফিরে আসে। আপনি যদি আপনার ওয়েবসাইটের সংস্থানগুলির সাথে অ্যাপ-মধ্যস্থ সামগ্রী মিশ্রিত করেন তবে অ্যাপ-মধ্যস্থ সংস্থানগুলির জন্য ডিরেক্টরি পাথগুলি, যেমন /assets/ বা /resources/ সংরক্ষণ করুন। সেই অবস্থানগুলিতে আপনার ওয়েবসাইট থেকে কোনও সংস্থান সংরক্ষণ করা এড়িয়ে চলুন।

কোটলিন

val assetLoader = WebViewAssetLoader.Builder()
                        .setDomain("example.com") // Replace this with your website's domain.
                        .addPathHandler("/assets/", AssetsPathHandler(this))
                        .build()

webView.webViewClient = LocalContentWebViewClient(assetLoader)
val inAppHtmlUrl = "https://example.com/assets/index.html"
webView.loadUrl(inAppHtmlUrl)
val websiteUrl = "https://example.com/website/data.json"

// JavaScript code to fetch() content from the same origin.
val jsCode = "fetch('$websiteUrl')" +
        ".then(resp => resp.json())" +
        ".then(data => console.log(data));"

webView.evaluateJavascript(jsCode, null)

জাভা

final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
           .setDomain("example.com") // Replace this with your website's domain.
           .addPathHandler("/assets/", new AssetsPathHandler(this))
           .build();

mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
String inAppHtmlUrl = "https://example.com/assets/index.html";
mWebView.loadUrl(inAppHtmlUrl);
String websiteUrl = "https://example.com/website/data.json";

// JavaScript code to fetch() content from the same origin.
String jsCode = "fetch('" + websiteUrl + "')" +
      ".then(resp => resp.json())" +
      ".then(data => console.log(data));";

mWebView.evaluateJavascript(jsCode, null);

ওয়েব-হোস্টেড JSON ডেটা আনার একটি ইন-অ্যাপ HTML পৃষ্ঠার উদাহরণের জন্য GitHub-এ WebView ডেমো দেখুন।

লোডডেটা উইথবেসইউআরএল

যখন আপনার অ্যাপ্লিকেশানটিকে শুধুমাত্র একটি HTML পৃষ্ঠা লোড করতে হবে এবং সাবরিসোর্সগুলিকে আটকাতে হবে না, loadDataWithBaseURL() ব্যবহার করার কথা বিবেচনা করুন, যার জন্য অ্যাপ সম্পদের প্রয়োজন নেই৷ আপনি নিম্নলিখিত কোড নমুনায় দেখানো হিসাবে এটি ব্যবহার করতে পারেন:

কোটলিন

val html = "<html><body><p>Hello world</p></body></html>"
val baseUrl = "https://example.com/"

webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)

জাভা

String html = "<html><body><p>Hello world</p></body></html>";
String baseUrl = "https://example.com/";

mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);

সাবধানে যুক্তি মান নির্বাচন করুন. নিম্নলিখিত বিবেচনা করুন:

  • baseUrl : এটি হল সেই URL যা আপনার HTML সামগ্রী হিসাবে লোড করা হয়েছে৷ এটি অবশ্যই একটি HTTP(S) URL হতে হবে৷
  • data : এটি হল সেই HTML সামগ্রী যা আপনি একটি স্ট্রিং হিসাবে প্রদর্শন করতে চান৷
  • mimeType : এটি সাধারণত text/html এ সেট করা আবশ্যক।
  • encoding : যখন baseUrl একটি HTTP(S) URL হয় তখন এটি অব্যবহৃত হয়, তাই এটি null এ সেট করা যেতে পারে।
  • historyUrl : এটি baseUrl এর মতো একই মান সেট করা হয়েছে।

আমরা দৃঢ়ভাবে একটি HTTP(S) URL হিসেবে baseUrl ব্যবহার করার পরামর্শ দিই, কারণ এটি নিশ্চিত করতে সাহায্য করে যে আপনার অ্যাপ একই-অরিজিন নীতি মেনে চলছে।

আপনি যদি আপনার সামগ্রীর জন্য একটি উপযুক্ত baseUrl খুঁজে না পান এবং loadData() ব্যবহার করতে পছন্দ করেন, তাহলে আপনাকে অবশ্যই শতাংশ-এনকোডিং বা Base64 এনকোডিং সহ বিষয়বস্তু এনকোড করতে হবে । আমরা দৃঢ়ভাবে বেস64 এনকোডিং বেছে নেওয়ার এবং এই প্রোগ্রামটিকে এনকোড করতে Android API ব্যবহার করার সুপারিশ করছি, যেমনটি নিম্নলিখিত কোড নমুনায় দেখানো হয়েছে:

কোটলিন

val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING)

webView.loadData(encodedHtml, mimeType, "base64")

জাভা

String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING);

mWebView.loadData(encodedHtml, mimeType, "base64");

এড়ানোর জিনিস

অ্যাপ-মধ্যস্থ সামগ্রী লোড করার আরও কয়েকটি উপায় রয়েছে, তবে আমরা তাদের বিরুদ্ধে দৃঢ়ভাবে সুপারিশ করি:

  • file:// URL এবং data: URL গুলিকে অস্বচ্ছ উত্স হিসাবে বিবেচনা করা হয়, যার অর্থ তারা fetch() বা XMLHttpRequest এর মতো শক্তিশালী ওয়েব APIগুলির সুবিধা নিতে পারে না। loadData() অভ্যন্তরীণভাবে data: URL, তাই আমরা এর পরিবর্তে WebViewAssetLoader বা loadDataWithBaseURL() ব্যবহার করতে উৎসাহিত করি।
  • যদিও WebSettings.setAllowFileAccessFromFileURLs() এবং WebSettings.setAllowUniversalAccessFromFileURLs() file:// URL-এর সমস্যাগুলি নিয়ে কাজ করতে পারে, আমরা এইগুলিকে true সেট করার বিরুদ্ধে সুপারিশ করি কারণ এটি করার ফলে আপনার অ্যাপটি ফাইল-ভিত্তিক শোষণের জন্য দুর্বল হয়ে পড়ে৷ আমরা সবথেকে শক্তিশালী নিরাপত্তার জন্য এগুলিকে স্পষ্টভাবে সকল API স্তরে false সেট করার সুপারিশ করি৷
  • একই কারণে, আমরা file://android_assets/ এবং file://android_res/ URL-এর বিরুদ্ধে সুপারিশ করি। AssetsHandler এবং ResourcesHandler ক্লাসগুলি ড্রপ-ইন প্রতিস্থাপনের জন্য বোঝানো হয়।
  • MIXED_CONTENT_ALWAYS_ALLOW ব্যবহার করা এড়িয়ে চলুন। এই সেটিংটি সাধারণত প্রয়োজনীয় নয় এবং আপনার অ্যাপের নিরাপত্তা দুর্বল করে। আমরা আপনার ওয়েবসাইটের রিসোর্স হিসাবে একই স্কিম-HTTP বা HTTPS-এর মাধ্যমে আপনার অ্যাপ-মধ্যস্থ সামগ্রী লোড করার এবং উপযুক্ত হিসাবে MIXED_CONTENT_COMPATIBILITY_MODE বা MIXED_CONTENT_NEVER_ALLOW ব্যবহার করার পরামর্শ দিই।