Android用のプラグインの作成

このサービスの結果、私は1年半前からAndroidプラットフォーム向けに執筆を続けており、この分野での私の知識は膨大であるように見えますが、すでにハブでカバーされているものの量は少なくありません。 一般に、よく検討した結果、このトピックについてhabra-peopleに伝えることにしました。



はじめに


そのため、たとえば、アプリケーション用に個別にダウンロード可能なゲームレベルまたは個別のテーマを作成します。 これ行うには3つの方法があります。



インターネットから追加のファイルをダウンロードすることですべてが明らかになるようです。主なことは、人気のあるアプリケーションに良いチャンネルを提供することです。 別のアプリケーションでは、材料費は少なくて済みますが、もう少し知的です。



実装


メインアプリケーションでは、必要なすべてのロジックが実装され、追加のリソースがプラグインアプリケーションに実装されます。さらに、メインアクティビティを少しやり直すことができます。これにより、これが単なるプラグインであることをユーザーに通知し、メインアプリケーションに送信します。 次の方法で実行できます。

Intent intent = new Intent(); intent.setClassName("package.name", "package.name.LauncherActivityName"); startActivityForResult(intent,REQUEST_CODE);
      
      





プラグインパッケージに名前を付ける最も簡単な方法 、1つのドメインを親パッケージに追加することです。 次に、メインアプリケーションからプラグインのリストを取得するために、現在のパッケージの名前を含むすべてのインストール済みアプリケーションに対してリクエストを行います。

 ArrayList<String> packs = new ArrayList<String>(); PackageManager mngr = context.getPackageManager(); List<PackageInfo> list = mngr.getInstalledPackages(0); for (PackageInfo packageInfo : list) { if (packageInfo.packageName.indexOf(context.getPackageName()) != -1 && !packageInfo.packageName.equals(DONATE_PACK) && !packageInfo.packageName.equals(FREE_PACK)) { packs.add(packageInfo.packageName);
      
      





多分少し冗長なコード。 パッケージ名が当社の名前に準拠しているかどうかの簡単なチェックに加えて、2つのアプリケーションがここにマークされています:アプリケーションの無料バージョンと寄付バージョン。 パッケージ名がわかれば、アプリケーションリソースにアクセスできます。

 PackageManager mngr = getPackageManager(); res = mngr.getResourcesForApplication(pack); if (res != null) {// use it!}
      
      





落とし穴


これを初めて実装したときに、R.string、R.idなどを介して目的のリソースに単純にアクセスしようとしました。 しかし、当然(現在-当然)、他のapkのRファイルの番号付けは異なります。最初に使用する必要があるリソースのIDを取得する必要があります。

 int id = res.getIdentifier("app_name", "string", pack); String name = res.getString(id);
      
      





上記の例では、idを取得し、タイプResourcesの既存のオブジェクトから受信したリソースを読み取ります。 ユーザーに既存のプラグインのリストを提供する必要がある場合、文字列の読み取りは私に適用されます。 この場合、R.stringsに追加することにより、ローカライズされた名前を提供する必要があります(「最初のアプリケーションを記述する..」の例を参照してください)。

さらに、レイアウトを読みたい場合は、それらを固定名と呼ぶこともできます。その後、同様の方法でリソースから取得できますが、ここでは...



落とし穴2


リソースがxmlで参照されている場所にレイアウトを展開すると、メインアプリケーションのリソースが使用されます。 つまり プラグインのレイアウトでボタンに特定の背景= "@ drawable / best_bg"があった場合、レイアウトを読み込んだ後、背景はプラグインのリソースにある要素ではなく、同じIDを持つメインプロジェクトの要素に移動します。それがまったく見つからない場合、そうでない場合-クラッシュ。 このようなことは避けてください:

 drawID = res.getIdentifier(layoutName + "_btn", "drawable", plugins[i]); Bitmap bmp = BitmapFactory.decodeResource(res, drawID); NinePatch patch = new NinePatch(bmp, bmp.getNinePatchChunk(), null); NinePatchDrawable drawable = new NinePatchDrawable(patch); btn.setBackground(drawable);
      
      





合計:プラグインのリソースからハンドル付きのリソースを取得し、受信した(ハンドルも)ビューに割り当てます。 同時に、このレイアウトにある要素のインスタンスを取得するために、次の構造を使用します。

 view.findViewWithTag(tag);
      
      





すべて同じ理由で-R.idを通じて彼女に連絡することはできません。

そして最後に。



落とし穴3


上記で見たように-私はNinePatchリソースを読みましたが、これらのninepatch.9.pngをプラグインプロジェクトに追加するだけで、非常に驚​​かれることでしょう-画像は通常の画像のように引き伸ばされます。 一番下の行は、adbがninepatchをコンパイルするということです-その後のみ使用できます。 プラグインでdrawableを使用すると、明らかに未コンパイルの元のリソースが提供されます。 あなたはそれを修正することができます、レシピはこれです:

  1. プラグインプロジェクトのコンパイル
  2. 解凍する
  3. 私たちはninepatch'iを取得し、プロジェクトで置換してコピーします
  4. もう一度コンパイル、利益


おわりに


厳密に判断しないようお願いします-これはハブに関する私の最初の投稿であり、たとえば、すべてを理解していません-コードをインデントする方法と、閉じたコードタグにもかかわらず、特定の行から始まる記事のテキストがコードが作成されたスタイルを持っている理由 上記が誰かに役立つことを願っています。 すべての1.6+プラットフォームでこのメソッドを正常に使用しますが、バグがなく、クラッシュしません。

このアプローチの唯一のマイナス点は、別個のアプリケーションとして存在するプラグインです。 しかし、Android Market'eでも、ライブラリには別のカテゴリがあります(その他/ライブラリとデモ)。

UPD:フォーマットを支援してくれたユーザーandycarambaに感謝します。



All Articles