posts - 235,  comments - 527,  trackbacks - 0

废话少说,如何使用KBMMW 做个过渡,使IOS 可以使用JAVA 的服务?

其实KBMMW 本身就要java service 的服务,但是为了把这个问题说清楚,我手工做一个例子。

 

首先,要使用JAVA 服务,JRE 是肯定要安装的。没有安装的话,自己去java.sun.com 去下载。

安装完毕, 命令行上运行 JAVA ,出现下图说明安装成功。

在服务器上首先祭起来JVM(JAVA 虚拟机)

 

function GetDllName: string;
var
  Registry: TRegistry;
  Version: string;
begin
  Result := 'jvm.dll';

  Registry := TRegistry.Create(KEY_READ);
  try
    Registry.RootKey := HKEY_LOCAL_MACHINE;
    if Registry.OpenKey('\SOFTWARE\JavaSoft\Java Runtime Environment', False) then
    begin
      Version := Registry.ReadString('CurrentVersion');
      if Version <> '' then
        if Registry.OpenKey(Version, False) then
          Result := Registry.ReadString('RuntimeLib');
    end;
  finally
    Registry.Free;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
 I: Integer;
  WebResult,WebMessage: String;

  n,e:integer;
  VM_args:JavaVMInitArgs;
  Options:array[0..20]  of JavaVMOption;
  Methods:array [0..0] of JNINativeMethod;
  OptCnt:integer;

  j_MainClass:JClass;
  LibraryFileName:string;
  Mid: JMethodID;

  FObj,tmpobj: JObject;
  FInit : JMethodID;
 
  mypath:string;
  myclasspath:ansistring;

  Env:PJNIEnv;
  JNIEnv:TJNIEnv;

const
  classpath='.;';
  JIT=True;
begin
 if G_javavm<>nil then
   begin
      meminfo.Lines.Add('JVM already created !');
      exit;
   end;



    n:=JNI_VERSION_1_4;

    LibraryFileName:= GetDllName;

    FillChar(Options,SizeOf(Options),#0);
    OptCnt:=0;

    mypath := g_RootPath;

    myclasspath:=classpath+mypath+'ws\ws.jar';

    Options[OptCnt].optionString:=PAnsiChar('-Djava.class.path='+ myclasspath);    
    inc(OptCnt);

    if not JIT then
    begin
      Options[OptCnt].optionString:=PAnsiChar('-Djava.compiler=NONE');
      inc(OptCnt);
    end;

    VM_args.version:=n;
    VM_args.options:= @Options ;//:=    @Options;
    VM_args.nOptions:=OptCnt;
    VM_args.ignoreUnrecognized:=1;

    g_JavaVM := TJavaVM.Create(n, LibraryFileName);

    e := G_JavaVM.LoadVM(VM_args);
    if e<0 then
    begin
      meminfo.Lines.Add ('Error loading JavaVM via JNI 1.4+. ErrorCode='+inttostr(e));

      exit;
    end;

    g_JNIEnv := TJNIEnv.Create(g_JavaVM.Env);
     meminfo.Lines.Add('JVM  create ok!');


end;

当然了,文件里面必须引用 JNI 单元。这个是kbmmw 自带的(此文件原来是JEDI 翻译jni.h 得,后来kbmmw 作者修改了,可以在新版delphi 中编译);

安装完虚拟机,就可以在delphi 中使用java 的class 了

下面就是一个简单的封装java 中hashmap 的例子

 

 1  Thashmap = class
 2   private
 3     FJNIEnv: TJNIEnv;
 4     FCls: JClass;
 5     FObj: JObject;
 6     FInit: JMethodID;
 7     FPut: JMethodID;
 8     FGet: JMethodID;
 9    public
10     constructor Create(JNIEnv:TJNIEnv;createobj:boolean=True);
11     procedure  put(ID,Text: string);
12     Function   get(ID: string):string;
13     property  hashmap: jobject read FObj write FObj;
14   end;
15 { Thashmap }
16 
17 constructor Thashmap.Create(JNIEnv: TJNIEnv; createobj: boolean);
18 begin
19   inherited Create;
20   FJNIEnv:=JNIEnv;
21   if FJNIEnv=nil then
22     raise Exception.Create('Please create JNIEnv');
23 
24   FCls  := FJNIEnv.FindClass('java/util/HashMap');
25   if FCls=nil then
26     raise Exception.Create('can''t find class HashMap');
27 
28   FInit := FJNIEnv.GetMethodID(FCls, '<init>', '()V');
29   if FInit=nil then
30     raise Exception.Create('can''t find init in class HashMap');
31 
32   Fput  := FJNIEnv.GetMethodID(FCls, 'put', '(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;');
33 
34   if Fput=nil then
35     raise Exception.Create('can''t find put in class HashMap');
36 
37   Fget  := FJNIEnv.GetMethodID(FCls, 'get', '(Ljava/lang/Object;)Ljava/lang/Object;');
38 
39   if Fget=nil then
40     raise Exception.Create('can''t find get in class HashMap');
41 
42   if createobj then
43   begin
44     FObj :=FJNIEnv.NewObjectA(FCls, FInit, nil);
45 
46     if Fobj=nil then
47       raise Exception.Create('can''t create a HashMap');
48   end;
49 end;
50 
51 function Thashmap.get(ID: string): string;
52 var
53   rets:Jstring;
54 begin
55   rets:=FJNIEnv.CallObjectMethod( FObj,Fget,[FJNIEnv.StringToJString(id)]) ;
56 
57   result:=FJNIEnv.JStringToString(rets);
58 end;
59 
60 procedure Thashmap.put(ID, Text: string);
61 begin
62   FJNIEnv.CallObjectMethod( FObj,Fput,[FJNIEnv.StringToJString(id),FJNIEnv.StringToJString(text)]);
63 end;

这样你就可以在delphi 中使用hashmap 了。

         if myhashmap<>nil then
            begin
             memo1.Lines.Add('hashmap already create!!')  ;
               exit;
            end;
            myhashmap :=Thashmap.Create(JNIEnv);
            memo1.Lines.Add('HashMap create ok!!');

            myhashmap.put('ROW_ID', ROW_ID);
            myhashmap.put('BILL_ID', BILL_ID);
            myhashmap.put('AUDIT_NODE', AUDIT_NODE);
            myhashmap.put('AUDIT_STATUS', AUDIT_STATUS);
           
            memo1.Lines.Add('put all data into hashmap');
            memo1.Lines.Add('ROW_ID:'+ myhashmap.get('ROW_ID'));
            memo1.Lines.Add('FLOW_ID:'+ myhashmap.get('FLOW_ID'));

 

那么由于kbmmw 是服务器端,肯定要考虑到多线程问题。

 

那么要在kbmmw servive 里面调用java 服务就要稍微处理一下。

示例如下:

function Tmysrv.JavaHashMapCheck(ClientIdent: TkbmMWClientIdentity;
  const Args: array of Variant): Variant;
var
  I: Integer;
  ROW_ID,BILL_ID: String;
  WebResult,WebMessage: String;

  n,e:integer;

  FObj,tmpobj, errorString: JObject;

  rets:Jstring;


  myhashmap:Thashmap;
 
   Env:PJNIEnv;
   JNIEnv:TJNIEnv;

  throwable:JThrowable;
   throwableClass:JClass;

begin
         Result := '';
           ROW_ID := Args[0];
            BILL_ID := Args[1];
        G_JavaVM.JavaVM^.AttachCurrentThread(G_JavaVM.JavaVM,@Env,nil);
         try
             JNIEnv:=TJNIEnv.Create(Env);

            
            if myhashmap<>nil then
            begin
             
              Result := '0';
              exit;
            end;
            myhashmap :=Thashmap.Create(JNIEnv);
           

            myhashmap.put('ROW_ID', ROW_ID);
            myhashmap.put('BILL_ID', BILL_ID);
          
         
            result:='return='+myhashmap.get('ROW_ID');

             throwable:=JNIEnv.ExceptionOccurred();
           if throwable<>nil then
           begin
                try
                   JNIEnv.ExceptionDescribe;
                   throwableClass:=JNIEnv.GetObjectClass(throwable);
                   if throwableClass<>nil then
                   begin
                        mid:=JNIEnv.GetMethodID(throwableClass,'toString','()Ljava/lang/String;');
                        if mid<>nil then
                        begin
                             errorString:=JNIEnv.CallObjectMethod(throwable,mid,[]);
                             if errorString<>nil then
                                kbmMWRaiseException(KBMMW_ERR_SERVICE_JAVA_EXCEPTION,string(JNIEnv.JStringToString(errorString)));
                        end;
                   end;
                finally
                   JNIEnv.ExceptionClear;
                end;
           end;



        finally
              myhashmap.Free;
              myhashmap := nil;
              tmphashmap.Free;
              tmphashmap := nil;
              myObjectUtil.Free;
              myObjectUtil := nil;
              JNIEnv.Free;
              G_JavaVM.JavaVM^.DetachCurrentThread(G_JavaVM.JavaVM);
          end;
end;


剩下的就是你自己处理了。

ios 里面按照老规矩调用kbmmw 服务就行了。

 

posted on 2016-07-31 12:34 xalion 阅读(...) 评论(...) 编辑 收藏