2013年3月28日木曜日

Android アプリケーション間FIFO通信


Androidにて複数アプリ間でデータのやりとりをするためにFIFOサービスを実装してみた。
実際にはAIDLを使えばええやん ・・ なのだが。

たとえばTCP通信をこのサービスで行い、やり取りした情報を他の複数アプリにばら撒くなどという使い方に利用できる。
このようにFIFOサービスを使うことで、複数アプリ間でデータの共通化が可能となる。

FIFOサービスの使用例


FIFOサービスの構成は以下のようにしている。
外部アプリとはAIDLでやり取りを行うために準備した。
実際のFIFOの制御は速度向上のためC++(JNI)で記述している。
またFIFOの本数は、ラッパークラスを配列で複数実装することにより対応できている。

FIFOサービス構成

実際のソースコードはここに置いている。
ソース一式はこちらから

 fifo.zip : このFIFOサービスを実現している環境一式
 fifotest.zip : このFIFOサービスと接続し、データをやり取りするためのテスト環境一式

fifotestはボタン1でFIFOへのデータ書き出し、ボタン2でFIFOからのデータ読出しを行います。

Androidによるデータの共有化、アプリケーション間FIFO通信などに利用してください。
JNIの部分を変更することで、SharedMemory(共有メモリ)のような使い方もできます。

ソースは理解できるかな? 慣れないとなかなか難しいかもしれませんね。
開発環境全体をダウンロードできるようにしていますので、Eclipseで動作確認してみてください。

動作原理がわかれば簡単です。がんばってトライしてみてください。

2013年3月27日水曜日

Android JNIでライブラリ作成

JNIで作ったC/C++ソースコードの使い回しはみんなどうしているんだろう?
ソースのコピペ?

コピペで新しいファイル作成も面倒なので、ライブラリ化してみた。

■ Android.mkの記述
    include $(BUILD_STATIC_LIBRARY)と記述する。



BUILD_SHARED_LIBRARYをBUILD_STATIC_LIBRARYに置き換える。
 
■ Application.mkの記述
   APP_OPTIM    := release
  APP_MODULES    := devInf ← モジュール名

モジュール名を定義する。
 これでCソースをビルドすると、objフォルダ内にライブラリファイル(libdevinf.a)が生成された。
■ ライブラリの使用
 生成されたライブラリを別のプロジェクトで使用してみる。
 ※新しいCソースには以下の記述を定義しておくことで、ライブラリ内の関数を呼び出すことができる。
  // ---------------------------------------------------------
//         devinfライブラリ内の関数定義
  // ---------------------------------------------------------
  extern void    _initDevInf( void );
 上記で生成されたライブラリ(libdevinf.a)をJNIフォルダにコピーし、Android.mkに定義を追記する。
  LOCAL_MODULE    := devicelib ← 一時的に生成するライブラリ名
LOCAL_SRC_FILES    := libdevInf.a ← 上記で生成したライブラリ名
  include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
  LOCAL_MODULE    := CheckInf
  LOCAL_SRC_FILES := checkInf.c ← 新しいプロジェクトのCファイル
  LOCAL_STATIC_LIBRARIES    := devicelib ← 一時的に生成するライブラリ名
  LOCAL_LDLIBS    := -llog

  include $(BUILD_SHARED_LIBRARY) ← .soライブラリを生成する


これでビルドすることで、いつものようにlibsフォルダ内にライブラリファイル(.so)が生成できた。

そうなんやぁ ・・ って感じ。
こんな使い方するのって誰もいないんかな?

Android JNI トラブル(ADT20130219版)


長年システム開発を行っているが、毎回ちょっとしたことでいろいろなトラブルに出会う。
その対策について、忘備録としてこのブログを使用しようと思う。
この忘備録が同様の開発者たちに少しでも役立てばと思う。

■ 今回のトラブル

   以前開発したAndroidアプリを新しい環境(adt-bundle-windows-x86-20130219.zip)にて再構築を行った際、JNIで開発したCソースが突然ビルドエラーとなった。

 何が悪いのだ? ・・ とにかく悩む。
 慣れないWindows版を使用したからか?
 慣れた環境(Ubuntu12.04 32bit版)でも同様の環境を構築してみたが、同じくSemantic Errorが発生しビルドできない。

■ ソースファイル

  #include <stdlib.h>
  #include "com_maxport_memtest_memtest01.h"
  JNIEXPORT jboolean JNICALL Java_com_maxport_memtest_funcmemtest( JNIEnv *env, jobject obj )
   {
       pByteDat = ( char * )malloc( 100 );
       return( true );
   }


mallocにSemantic Error発生!
長年使い慣れたmalloc関数でこんなエラーはどう考えてもありえない。
何がどう違うのかさっぱりわからない状態で時間だけが経過していった。

※ malloc、memset、read、writeなどに同様のエラーが発生している。

■ 対策

 結局はEclipseのビルド環境設定を見直しただけで解決できた。

 プロパティ → C/C++ General → Code Analysis 
 ここで Invalid arguments のエラーチェックを外せばよい。

 ※ こちら日本語化していないので、 日本語化した場合の表示内容は不明。

Invalid argumentsのチェックを外す。
  ビルドエラーはなくなり、無事にビルド完了!

 以前の環境(2012年9月あたりにUbuntu12.04上で構築した環境)では問題なかったので、新しい環境でこうなってしまったのだろう。
 OSや開発環境のバージョンアップにいつも振り回されてばかりだ ・・・