精华内容
下载资源
问答
  • 简介javaagent 是 Java1.5 之后引入的新特性,其主要作用是在class被加载之前对其拦截,以插入我们的字节码。java1.5 之前使用的是JVMTI(jvm tool interface)...jar常见的jar包分为 可运行jarjavaagent.jar ,...

    简介

    javaagent 是 Java1.5 之后引入的新特性,其主要作用是在class被加载之前对其拦截,以插入我们的字节码。

    java1.5 之前使用的是JVMTI(jvm tool interface)技术来实现对class的拦截,不过这个是用 C++ 编写的,比如 debug 功能就是用这个技术实现的,有兴趣的自行百度。

    jar

    常见的jar包分为 可运行jar 和 javaagent.jar ,它们的主要区别如下:

    Executable Jar

    Javaagent Jar

    入口方法

    main

    premain

    打包参数

    Main-Class

    Premain-Class

    启动方式

    java -jar xxx.jar

    -javaagent:xxx.jar=dddd

    是否可启动

    入口方法

    可运行 jar 包入口方法:

    package org.coderead;

    public class TestMain {

    // 这个是我们经常写的

    public static void main(String[] args) {

    System.out.println("hello main");

    }

    }

    javaagent.jar 入口方法:

    package org.coderead;

    import java.lang.instrument.Instrumentation;

    public class TestAgent {

    public static void premain(String arg, Instrumentation instrumentation) {

    System.out.println("javaagent arg=" + arg);

    }

    }

    MANIFEST.MF 文件方式

    Use Your Own Manifest File 这篇官方文档介绍了使用 MANIFEST.MF 打包的方法:

    ...

    org.apache.maven.plugins

    maven-jar-plugin

    ...

    src/main/resources/META-INF/MANIFEST.MF

    ...

    ...

    默认情况下,Maven Archiver为您创建清单文件。有时使用您自己手工制作的清单文件很有用。假设您要使用清单文件 src/main/resources/META-INF/MANIFEST.MF。 通过将 配置元素设置为文件的位置来完成此操作。

    您自己的清单文件的内容将与Maven Archiver创建的条目合并。 如果您在自己的清单文件中指定一个条目,它将覆盖Maven Archiver创建的值。

    注意:与此处的所有示例一样,此配置可以在所有使用Maven Archiver的插件中使用,而不仅仅是本示例中的maven-jar-plugin。

    打包一个可运行 jar 包 Executable.jar 的 MANIFEST.MF

    Main-Class: org.coderead.TestMain

    注意:

    MANIFEST.MF 中需要多留一个空行,也就是输入完成最后一行之后回车

    打包一个 javaagent 包 javaagent.jar 的 MANIFEST.MF

    Premain-Class: org.coderead.TestAgent

    Maven 项目结构

    首先是 可运行jar 的项目结构:

    e84ff44860f0da7f2051c756377724c4.png

    然后是 javaagent.jar 的项目结构:

    9e636309d51ee53c9fd37470be01809d.png

    package 打包 jar

    8bc418b78f0a7fdc9a62ffc99b611729.png

    这个对应的命令是mvn package, 打包后会生成 target文件,并且生成 jar 包。

    如果在 IDEA 没有找到右边栏,你可能需要点击IDEA左下角的按钮

    318ce4da99e82029d843c04ec7b8fb0f.png

    验证

    我在对两个项目执行了 package 之后,把 target\executable-1.0.jar 和 target\javaagent-1.0.jar 移动到同一个文件夹下,比如我在桌面新建了一个 test 文件夹。

    然后执行命令

    java -javaagent:javaagent-1.0.jar=test -jar executable-1.0.jar

    执行结果如下图所示

    077b6a1bfcaa1e4b5dccda06b58fe992.png

    manifestEntries 标签

    还可以使用 代替创建 MANIFEST.MF 文件。这样就更加省事了!少创建一个文件!

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    4.0.0

    org.coderead

    javaagent

    1.0

    org.apache.maven.plugins

    maven-jar-plugin

    org.coderead.TestAgent

    *manifest 标签

    借助 标签,我们可以指定可运行 jar 的主类。

    参考官方文档 中关于标签讲解。

    value

    value

    因此,我们的代码还可以写成

    ...

    org.apache.maven.plugins

    maven-jar-plugin

    ...

    org.coderead.TestMain

    ...

    ...

    总结

    我们有两种方式来使用 Maven 打包 javaagent.jar 。

    一种方式是在 标签中指定 META-INF/MANIFEST.MF 文件路径。在文件中填入 javaagent 打包属性。

    另一种是在 标签下,直接设置 javaagent 打包属性标签。

    如果是打包可运行 jar 包,除了前两种方法外,第三种是使用 manifest 标签。

    MANIFEST.MF 文件必须要在输入完最后一行配置后输入回车,即留出一行空白行

    本文打包使用的插件是 maven-jar-plugin,生成 jar 包的命令是 mvn package

    打包 javaagent.jar 必须指定 Premain-Class:org.coderead.TestAgent

    展开全文
  • 2Pascal-新时代的Pascal-关于 调用 JNI JAR java 的说明和注意事项,调用第 靠写不下了 - Powered by Discuz! 关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码 的说明 V2017.10.18...

    2Pascal-新时代的Pascal-关于 调用 JNI JAR java 的说明和注意事项,调用第 靠写不下了 - Powered by Discuz!

    关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码 的说明 V2017.10.18

    (* ************************************************ *)
    (*                         *)
    (*                         *)
    (*  设计:爱吃猪头肉 & Flying Wang 2015-04-15   *)
    (*      上面的版权声明请不要移除。      *)
    (*                         *)
    (* ************************************************ *)

    本人所在的群(① FireMonkey[移动开发]  165232328)


    对于安卓系统
    谷歌 API 提供的是 JNI 接口。
    第三方 JAR SDK 提供的也是 JNI 接口。

    您的手机,一般会内置 安卓 SDK 的大部分接口。
    但是有些 API 可能没有内置。

    FMX 安卓工程默认会给您提供多个 谷歌的 SDK 。
    因此 大部分 谷歌的 JAR,您都不需要自己去找。

    对于 第三方的 SDK 来说。
    基本上分为 jar + so、纯jar 和 纯so 三种。
    纯so 就是类似于 dll 的接口。只需要注意 dll 是 stdcall 类型,其他所有平台都是 cdecl 类型。 不写是不行的。因为 delphi 不写的是默认的 pascall 类型。
    如果你不会调用 dll 那么也就不会调用 so 。
    本文不讨论调用 so。

    但是告诉你们 SO 文件文件的路径:编辑 RemotePath 列。路径是(xe5) library\lib\armeabi   (xe6或以上) library\lib\armeabi-v7a
    以上路径的 so 一般是给 jar 加载用的。
    自己加载可以用 LoadLibaray 或者 dlopen 。记得用对应的 FreeLibaray 和 dlclose
    也可以像定义 DLL 一样,定义 so 的函数接口。这样就不用写代码加载了。
    如果只有你自己用,也可以发布到其他你能访问的路径。但是,只能写代码加载了,路径要写完整。

    armeabi-v7a 是 arm32 的,如果你需要支持 64bit 除了这个目录,还需要 arm64-v8a。
    64bit 下凡是需要用到 so 的,这两个目录都需要放对应的 so。


    对于 jar 无论它有没有提供 so 。我们都只能使用 jar 的对外接口。

    除非是安卓基本 API,或者是 DELPHI 已经提供的 JAR 。否则 其他的 JAR ,只要你用到了,就必须加入到 安卓的 工程中。 具体如何添加,请自行百度。

    即便是 基本 API,EMBT 也没有全部给大家 转成 JNI 接口。
    所以当你用到一个 EMBT 没翻译的 API 的时候,请自行用 工具 翻译。

    翻译:可以理解为 语言的转换,接口的导出,也就是变成 pascal语法的 pas 文件

    当你得到一个 JAR 的时候,请用工具翻译成 pascal 文件。
    目前推荐 2 个 工具。
    1. 官方的 java2op.exe 。支持 .jar .java .class 三种格式的文件。
    2. 爱吃猪头肉的 JarOrClass2pas 。支持 .jar .class 两种格式的文件。

    其他工具都是垃圾。千万别用。否则活该。

    当你用工具得到 pas 文件后,注意:
    1. 一般会得到 大量的 无用的,错乱的,重复的 接口。请将它们删除。
    2. 即便是没问题的接口,如果用不到,也请删除。
    3. 转换工具会写出一些 uses 的单元,这些单元可能不存在。

    对于jar 或 class 文件引用了别的 jar,就容易出现不认识的 unit 的 uses。请找到这些 jar 继续翻译。


    当你 jar 已经加入到 安卓项目中。
    jni pas 文件已经准备好,也加入到 安卓项目中。
    就可以开始调用 jar 接口了。


    接下来说明下基本的类型变化。

    Int 就是 Integer ,很多基本对象大家都可以自己想到。
    string 是 JString 。
    Uri 要翻译成 Jnet_Uri。
    上述两个类型 EMBT 提供了互相转换的函数。
    还有个别的其他改变名称的类型。这里就无法一一列举了。如果 你发现一些 类名 EMBT 应该提供了,但是找不到,请通过 Signatur 在 Find in Files 对话框中查找。
    例如 搜索 java/lang/Class 可以发现 JCalss 也改名了。

    int [] 就是 TJavaArray<Integer> ,基本类型用 TJavaArray<>。
    但是 string [] 是 TJavaObjectArray<JString>,对象类型的一般都用 TJavaObjectArray<>。

    ArrayList<String> 要翻译成 JArrayList
    而且任何 ArrayList<PendingIntent> 也就是 ArrayList<某对象> 都要翻译成 JArrayList。

    有些类型的名称比较特别。例如 java 的 Phone 类型 EMBT 已经翻译成了 JCommonDataKinds_Phone。这是因为 Phone 是 CommonDataKinds 的内部类。


    数据类型 OK 了。那么就谈谈 Java 类的 构造函数 类成员 类方法 和 普通成员 普通方法。
    如果不懂这些,请自行百度。建议好好看看 面向对象开发 课程。

    Java 类一般会提供默认构造函数,到了 pas 里头,他的函数名叫 init 小写。默认不带参数。
    但是很多 java 类 会重载 构造函数,提供带参数的版本。


    接下来,我们需要百度下你打算使用的 jni 的 demo 。
    安卓开发,最大的优势就是,网上全是 demo ,虽然是 java 语言的。

    找到 demo 代码之后,你就需要 按照 代码的逻辑,进行语言的翻译。

    下面提供几种常见的 代码 翻译。
    关键内容,请回复。

    本帖隐藏的内容

    1 某对象的 构造。
    1.1 java 代码
      xxx x = new xxx(参数或没有参数);
    1.2 翻译代码
    var
      x: Jxxx;
    begin
      x := TJxxx.JavaClass.init(参数或没有参数);
      if x = nil then 出错了。
    end;
    上述代码,演示了构造函数的使用。 注意:
    1.3 x 是 Jxxx
    1.4 TJxxx.JavaClass 是 TJ 开头的。JavaClass. 能提供给你 这个类的所有类方法,类成员,包括构造函数。
    1.5 不是所有类都可以使用默认构造函数的。
    1.6 如果你确认可以使用默认构造函数,但是 pas 中没有。可以使用如下代码构造。
      x := TJxxx.Create;

    2. 某对象的 非默认构造,使用类方法的构造。
    2.1 java 代码 通过 new 创建对象。
      xxx x = new xxx.yyy(参数或没有参数);
    2.2 java 代码 不通过 New 创建对象。
      xxx x = xxx.yyy(参数或没有参数);
    2.3 翻译代码
    var
      x: Jxxx;
    begin
      x := TJxxx.JavaClass.yyy(参数或没有参数);
      if x = nil then 出错了。
    end;
    上述代码,演示了使用类方法来得到类 xxx 的对象。

    3. 通过其他类的对象,来得到对象 x。
    3.1 java 代码
      xxx x = yyy.zzz(参数或没有参数);
    3.2 翻译代码
    var
      x: Jxxx;
    begin
      x := yyy.zzz(参数或没有参数);
      if x = nil then 出错了。
    end;
    非常简单,就是加了个冒号。yyy 是另一个对象。 zzz 可以是 yyy 对象的类方法、类成员、普通方法或普通成员。


    4. 通过强制类型转换,来得到对象 x,一般不常用。
    4.1 java 代码
      xxx x = (xxx)yyy.zzz(参数或没有参数);
      zzz 返回的类型不是 xxx,也不是 xxx 的派生类。
    4.2 翻译代码
    var
      xLocalObject: JObject;
      x: Jxxx;
    begin
      xLocalObject := yyy.zzz(参数或没有参数);
      或者
      xLocalObject := JObject(yyy.zzz(参数或没有参数));

      if xLocalObject = nil then 出错了。
      x := TJxxx.Wrap((Obj as ILocalObject).GetObjectID);
      if x = nil then 出错了。
    end;
    注意 Wrap 的开头,也是 TJ
    经过 [臺北]wildsky(2590003092) 的验证
    x := TJxxx.Wrap((yyy.zzz(参数或没有参数) as ILocalObject).GetObjectID);
    这样少一个变量的写法。部分机器发生闪退。
    用两个变量来完成,就不会发生闪退,我个人觉得这个肯定不是问题的原因,下面才是。

    对于某些 JNI 服务
    经过 [深圳]机器猫(5909386)  的验证
    TJContext.JavaClass.VIBRATOR_SERVICE
    TJActivity.JavaClass.VIBRATOR_SERVICE
    用上面个可以,下面的就会闪退。
    出现的错误提示可能是:Project xxx.apk raised exception class Aborted(6).




    J 开头 TJ 开头 都是 约定俗成。你也可以 SB 开头 TSB 开头。

    默认 TJ 开头的是 DELPHI 的类型。
    J 开头的才是 JAVA 的类型。

    TJxxx.JavaClass 返回 JxxxClass 类型,这个类型专门代表类方法和类属性。 Jxxx 则代表类对象的类型。

    5. 不通过变量来操作某类型 xxx 的代码。
    5.1 java 代码
      xxx.yyy(参数或没有参数).zzz(参数或没有参数);
    5.2 翻译代码
      TJxxx.JavaClass.yyy(参数或没有参数).zzz(参数或没有参数);
    5.3 xxx 是类型 yyy 是类函数。
    5.4 可以出现 xxx.JavaClass.yyy(参数或没有参数).zzz(参数或没有参数).nnn(参数或没有参数); 这种多级的调用。

    6. 已存在对象 xxx 调用他的方法来操作的代码。
    6.1 java 代码
      xxx.yyy(参数或没有参数);
    6.2 翻译代码
    xxx.yyy(参数或没有参数);
    6.3 xxx 是对象 yyy 是该对象的类函数或成员函数。
    6.4 可以出现 xxx.yyy(参数或没有参数).zzz(参数或没有参数); 这种多级的调用。

    7. 使用常量
    7.1 java 中的常量,一般都是类的成员。而且一般是类的类成员。
    7.2 java 代码
      xxx = yyy.zzz;
      //xxx 是一个变量 yyy 是一个类名 zzz 是常量名
    7.3 翻译代码
      xxx := TJyyy.JavaClass.zzz;
    7.4 也就是说 zzz 被翻译到了 Jyyy 的 Class 版本的 接口中。
    7.4 效果等于
      xxx := JyyyClass.zzz;
    7.5 不建议用上面的代码。请按 7.3 的版本写。

    注意,对于我们 pascal 来说没有参数括号是可以省略的。 C JAVA 等是不允许省略的。


    对于 数组 TJavaArray<XXXX> 如果你特别想自己建立对象。
    可以写
    var
    xxx: TJavaArray<XXXX>;
    begin
      xxx := TJavaArray<XXXX>.Create(个数);
      然后用 xxx.Items[编号] 来访问。
    end;
    TJavaObjectArray 也是如上的办法。
    目前没有发现动态修改数量的办法。也就是数组的个数,是建立的时候就确定的。

    8. 一些常用的 Jni 和 pascal 类型的互转
    打开
    unit Androidapi.Helpers;
    自己去看吧。
    有 TBytes string  JCharSequence JURI JLong 等几种常用类型的互转。





    如果你使用一个方法,发生Segmentation fault(11) 可能是对象为 nil 或者 函数不存在(一般是版本不同,有的版本函数就不存在)。

    如果你使用一个方法,发生非法操作,说明没有这个方法(大概是名称或参数有错误)。
    如果提示你 java class xxx could not be found,如果是官方 xxx ,那么是你的手机内部没提供这个接口,你可以自己找官方的 jar 文件来加入、
    如果是第三方的 xxx,那更简单了,这个 xxx 对应的 jar 文件,你肯定没加入到 你的工程中。
    如果你确认你加了(参考

    第二个箭头,确认加了,就删了再加一遍,还不行,可能是你编译出的结果目录,存在垃圾,删除编译结果目录试试。),建议做如下操作
    打开你的 Android 工程,点菜单项 Project—>Deployment,打开部署子窗口,点 Revert to Default 按钮,就是那个向左的弯箭头:
    出现 Revert to default 对话框:
    选中第一项“Revert for all configurationsthe active platform”,点 OK。
    注意:不论其默认选项如何,在这里都必须选择其中一个并点OK,否则你的Android程序在调用JAR文件时将会出现“Java Class xxx could not befound”的错误。
    以上文字来源于 http://blog.sina.com.cn/s/blog_648d306d0102vfgq.html


    如果 Objs 是 TJavaObjectArray<Jxxxx> 的 Objs.Items[x] 或者 Objs[x] 发生错误(Segmentation fault(11)),那么就是不能这样用,改用
    TJxxxx.Warp(Objs.GetRawItem(x)) 试试。多谢 [深圳]机器猫(5909386)  的测试。


    一般建议
    uses
    {$IF CompilerVersion >= 27.0} // >= XE6
      Androidapi.Helpers,
    {$ENDIF}
      FMX.Helpers.Android,
      Androidapi.JNI.JavaTypes,
      Androidapi.NativeActivity;

    关键内容,请回复。

    本帖隐藏的内容

    当需要一个 Activity 对象的时候,我们只能提供 TAndroidHelper.Activity。因为 FMX 只存在这个一个 Activity。java UI 代码中 self(this) 就是 Activity 对象。
    当需要一个 View 对象的时候,默认的是 TAndroidHelper.Activity.getWindow.getDecorView。其他的就不知道了。
    当需要一个 Context 对象的时候,可以试试 TAndroidHelper.Context,这是全局的。
    当你需要一个 getApplicationContext 对象的时候,可以试试 TAndroidHelper.Context.getApplicationContext,这是因为你不懂自己看源码,不是我的错。
    {$IF CompilerVersion >= 30.0} // >=RAD10
        TAndroidHelper.Activity
        TAndroidHelper.Context
    {$ELSE}
        SharedActivity
        SharedActivityContext
    {$ENDIF}




    无论如何,当你得到一个 java 对象一定要先检查 是不是 nil,否则轻则提示错误,重则闪退。
    EMBT 经常忘了检查,所以就闪退,例如你在窗体中放了一个 IAP 支付控件,很多手机上都会闪退,就是因为没检查 nil。
    如果是正在开发的 APP 在任何机器上闪退,特别是旧版本升级来的,别人复制给你的。一般是 发布信息混乱,造成的。工程的 发布(部署)信息需要【重新加载】。Deployment 需要 Revert to Default
    如果是任何APP。包括新建的空 APP,在特定的机器上一运行就闪退。说明是一个 BUG。请在本群的 不看后悔 系列中 解压 找 XE 修复 APK 启动,提示 Cannot deploy," " file not found.txt。

    当你使用一个 jni 对象的时候。如果是个可以显示的对象。很多时候需要:
    CallInUiThread(
        procedure
        begin
          jni 代码。
        end);
    有时候 还得换成 CallInUIThreadAndWaitFinishing。
    只有这样 代码才不会死锁。
    也就是 如果不这么写。你的 APP 就会出现 未响应。
    有些不是显示的 jni 对象,也需要这样写。不过不常见。
    如果你收到一个错误 CalledFromWrongThreadException,就是需要 CallInUiThread 了。

    如果收到的是
    Can't create handler inside thread that has not called Looper.prepare()
    也是需要 CallInUiThread 了。多谢 [新会]supermay(15832782) 测试。

    注意:不要将大片代码进入上述的代码块中。尽量减少相关代码。最好是用 DEBUG ,找出弹出这类错误提示的代码行。不会 DEBUG 请看书。

    在 安卓的世界里,回调函数是不存在的。但是可以使用接口来做到回调。
    一般这种接口 会被定义成 Listener。

    当你需要继承(实现)一个 java 接口的时候,就需要查看有关代码了。

    本帖隐藏的内容

    使用 DELPHI IDE,在 Search 菜单打开 Find In Files 对话框。
    输入搜索关键字
    = class(TJavaLocal,
    搜索范围 Search in directories
    选择到你的安装目录的源代码目录,选中 Indude subdirectories
    好好找吧。



    你会找到好多代码。
    他们都是继承(实现) java 接口的好例子。

    按照面向对象的说法 接口必须实现。所以上面找到的代码是必然的。
    然后定义出这个类的 对象,就可以当参数在 jni 中使用了。
    不过这种类型,是 delphi 的实现,所以别忘了 free。

    个人建议大家好好研读【unit System.Android.Bluetooth;】。

    有时候 接口提供的 回调函数 可能是在线程中运行的。
    这时候你实现这个函数的时候,要注意。
    UI 对象 无论是 FMX 的还是 jni 的。你都需要线程同步。

    线程同步的简单方法就是。
    ...
    //线程或回调函数里的一些代码。
    TThread.Synchronize(nil, //或者 用线程自己的同步函数。 Synchronize(
            procedure
            begin
              //你的界面交互代码。
            end);
    //继续线程或回调函数的代码。
    ...

    如果是调用事件,
    建议用
    TThread.Queue(nil,
            procedure
            begin
              //你的事件调用。
            end);


    如果你 DEBUG 中收到了 Bitmap size too big 的提示,有可能就是 该用同步,没同步造成的。
    10.2 以后,不会再有这个提示。 Bitmap 支持线程中使用了。

    10.2 开始,主线程和 UI 线程 为同一个线程了。
    CallInUiThread 应该可以大批量的不用了。


    有了以上知识,你基本上翻译 java 的代码,就不成问题了。
    别说,你不会 顺序、判断、循环、函数调用。

    如果你想了解一个 第三方 view 是如何显示到 FMX 中的。
    可以参考 unit FMX.WebBrowser.Android 和 unit FMX.Media.Android。

    另外,很多操作,都需要对应的权限,别忘了加上。

    对于 4.4 以上的系统,想要访问外置存储卡。需要加上
    <uses-permission android:name="android.permission.READ_MEDIA_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"/>
    这 2 个权限。
    目前 IDE 没有提供。
    您需要在 AndroidManifest.template.xml 文档中,自己加入,用 IDE 就能打开,找到 <%uses-permission%>,将上述权限文字加入到 这行下面就行。
    但是,不保证所有机器都有效。


    如果发现需要使用 安卓下面的 命令行,例如执行 su sh ping 等。
    可以参考 QDac http://blog.qdac.cc 的代码,可能叫 QRuntime。
    也可以参考 本群的 重启你的手机 源代码。


    对于学习 翻译 安卓 java 代码为 pascal 。
    最好先看 EMBT 的源代码。然后看 EMBT 的 Samples。
    也可以好好看 本群的群共享。
    里头好多调用 jni 的 DEMO。 

    相关工具
    一种简单的 jar 转 pas 工具,不如 EMB 官方提供的 工具 强大。
    JarOrClass2Pas FlyingWang V1.0.2016.426 附赠 java 转 Jar.zip
    2Pascal-新时代的Pascal-JarOrClass2Pas FlyingWang 1.0.2020.1116.27 附赠 java 转 Jar.zip - Powered by Discuz!
    (出处: 2Pascal-新时代的Pascal)

    如果你希望使用 EMB 官方工具,请打开你的 帮助,搜索 Java2OP.exe 。


    RAD10RTM 加载 jar 存在 BUG
    Log in - Embarcadero Technologies
    QC 中有解决办法。
    建议去 EMB 官网注册 EDN 账号,即可登录。
    上面的  BUG 新版本已经 FIX 了。


    手动翻译 JNI 的老文章
    JNI 翻译 转 Delphi 的 经验 方法
    http://www.2pascal.com/forum.php ... &tid=1100&fromuid=4
    (出处: 2Pascal-新时代的Pascal)

    可以参考的 DEMO。

    BaiduLocation_百度定位_LBS_定位_5_SDK_DEMO_Add_Jar_BaiduLBS_Android5
    2Pascal-新时代的Pascal-BaiduLocation_百度定位_LBS_定位_5_SDK_DEMO_Add_Jar_BaiduLBS_Android5 - Powered by Discuz!
    (出处: 2Pascal-新时代的Pascal)


    安卓 服务 的 一些 相关代码,自动启动服务或定时启动APP。
    2Pascal-新时代的Pascal-安卓 服务 的 一些 相关代码,自动启动服务或定时启动APP。 - Powered by Discuz!
    (出处: 2Pascal-新时代的Pascal)


    专门的 DELPHI 实现 JAVA 接口 的 DEMO。
    消息注册接收 DEMO。
    Java 的消息及事件的一般做法的 DELPHI 版 源码。

    安卓 接口实现的事件 动态注册 接收 WIFI 变化消息 Demo
    http://www.2pascal.com/forum.php ... &tid=3008&fromuid=4
    (出处: 2Pascal-新时代的Pascal)


    反射调用 java api
    java demo
    [mw_shl_code=java,true]    /**
         * VIVO
         * <p>
         * android.util.FtFeature
         * public static boolean isFeatureSupport(int mask);
         * <p>
         * 参数:
         * 0x00000020表示是否有凹槽;
         * 0x00000008表示是否有圆角。
         *
         * @param context Context
         * @return hasNotch
         */
        private static boolean hasNotchInVivo(Context context) {
        boolean hasNotch = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class ftFeature = cl.loadClass("android.util.FtFeature");
            Method[] methods = ftFeature.getDeclaredMethods();
            if (methods != null) {
                for (int i = 0; i < methods.length; i++) {
                    Method method = methods;
                    if (method.getName().equalsIgnoreCase("isFeatureSupport")) {
                        hasNotch = (boolean) method.invoke(ftFeature, 0x00000020);
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            hasNotch = false;
        }
        return hasNotch;
    }[/mw_shl_code]

    作者:brucevanfdm
    链接:漫谈Android手机刘海屏(附工具类) - 简书


    delphi demo

    本帖隐藏的内容

    [mw_shl_code=delphi,true]const
      VIVO_NOTCH = $00000020;//是否有刘海
      VIVO_FILLET = $00000008;//是否有圆角

    type
      JMethodInvoke = interface;

      JMethodInvokeClass = interface(JObjectClass) // or JObjectClass // SuperSignature: java/lang/reflect/AccessibleObject
      ['{78FDACCD-05FA-478C-AA11-4BF4794DFC7C}']
        { static Property Methods }

        { static Methods }

        { static Property }
      end;

      [JavaSignature('java/lang/reflect/Method')]
      JMethodInvoke = interface(JObject) // or JObject // SuperSignature: java/lang/reflect/AccessibleObject
      ['{6190D24D-0B94-4836-92C4-7F8B23C4FC9B}']
        { Property Methods }

        { methods }
        function invoke(receiver: JObject; args: TJavaObjectArray<JObject>): JObject; cdecl; //(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

        { Property }
      end;

      TJMethodInvoke = class(TJavaGenericImport<JMethodInvokeClass, JMethodInvoke>) end;

    var
      IsVivoFeatureSupportMethod: JMethodInvoke = nil;
      ftFeatureClass: Jlang_Class = nil;
    function IsVivoFeatureSupport(Mask: Integer): Boolean;
    begin
      Result := False;
      try
        if (IsVivoFeatureSupportMethod = nil) or (ftFeatureClass = nil) then
        begin
          var ClassName := 'android.util.FtFeature';
          var MethodName := 'isFeatureSupport';
          var Signature := '(I)Z';

          if IsCanFindJavaStaticMethod(MethodName, Signature, ClassName) then
          begin
            //Result := TJFtFeatureUtil.JavaClass.isFeatureSupport(Mask);
            //狗屁 vivo 一定要用反射调用。
            var cl:JClassLoader := TAndroidHelper.Context.getClassLoader;
            ftFeatureClass := cl.loadClass(StringToJString(ClassName));
      //      var methods:TJavaObjectArray<JMethod> := ftFeatureClass.getDeclaredMethods;
            var methods:TJavaObjectArray<JMethod> := ftFeatureClass.getMethods;
            if (methods  <> nil) then
            begin
              var method: JMethod := nil;
              for var I := 0 to methods.length - 1 do
              begin
                method := methods[I];
                if (method.getName.equalsIgnoreCase(StringToJString(MethodName))) then
                begin
                  IsVivoFeatureSupportMethod := JMethodInvoke(method);
                  break;
                end;
              end;
            end;
          end;
        end;
        if (IsVivoFeatureSupportMethod <> nil) and (ftFeatureClass <> nil) then
        begin
          var args := TJavaObjectArray<JObject>.Create(1); //maybe auto free
          try
            args.Items[0] := TJInteger.JavaClass.init(Mask);
            Result := JBoolean(IsVivoFeatureSupportMethod.invoke(ftFeatureClass, args)).booleanValue;
          finally
            FreeAndNil(args);
          end;
        end;
      except
        Result := False;
      end;
    end;[/mw_shl_code]

     

     

    展开全文
  • 这是处理JAR App中所有图像和图标的最佳方法。将所有图像和图标压缩到其自己的JAR文件中之后-通过将图像JAR文件添加到“库”选项卡中来配置构建路径,以使其现在包含在类路径中。然后,只需在构造函数的开头使用以下...

    这是处理JAR App中所有图像和图标的最佳方法。

    将所有图像和图标压缩到其自己的JAR文件中之后-通过将图像JAR文件添加到“库”选项卡中来配置构建路径,以使其现在包含在类路径中。

    然后,只需在构造函数的开头使用以下3x代码行即可访问所需的任何图像,包括不接受简单ImageIcon作为其主要图标的SystemTray图像(我知道这很奇怪)。3x行是:

    URL iconUrl = this.getClass().getResource("/image-iconb.png");

    Toolkit tk = this.getToolkit();

    someimgicon = tk.getImage(iconUrl);

    (someimgicon只是一个声明了Image变量的构造函数) 现在,您可以将窗口图标设置为:

    setIconImage(someimgicon);

    并通过声明以下内容在设置系统TrayIcon时使用相同的变量:

    trayIcon = new TrayIcon(someimgicon, "SystemTray Demo", popupMenu);

    上面的代码使您可以轻松,集中地声明Image或ImageIcons,而不会冒未将图像资源放置在正确位置的风险。JAR包含您在运行时自动编译的所有图像以及程序的分发,从而使其保持整洁。

    另外,一旦在类路径中注册了JAR,您就可以随时将任何其他图像添加到同一JAR中,而不必大惊小怪-一切正常,添加的图像可立即用于您的应用程序。

    展开全文
  • 编写start.sh脚本#!/bin/bash export JAVA_HOME=/opt/app/jboss-eap-6.4/jdk1.7.0_71 export PATH=$JAVA_...export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar java -version java -jar hello.jar
    1. 编写start.sh脚本
      #!/bin/bash
      export JAVA_HOME=/opt/app/jboss-eap-6.4/jdk1.7.0_71
      export PATH=$JAVA_HOME/bin:$PATH
      export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
      java -version
      java -jar hello.jar
      
    展开全文
  • Java中常用的jar包有哪些发布时间:2020-06-22 11:26:02来源:亿速云阅读:108作者:Leah今天就跟大家聊聊有关Java中常用的jar包,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家...
  • 看看我在google上找到的代码,它应该解释如何动态加载jar:import java.io.File;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;/*** @author Thomas.Darimont*/public class...
  • 参考了几篇文章加载jar包的类URLClassLoader中使用的方法为addURL,但是这个方法是protected类型分别用了两种方法一、反射到这个类Methodadd=URLClassLoader.class.getDeclaredMethod("addURL",newClass[]{URL.class...
  • 可能很多初学者和我一样,在初次接触java开发的过程中,急于看到最终的结果,匆匆在网上下载了jdk之后,点击安装,结果等安装完,开始配置classpath时,发现jdk/lib下面根本就没有 tools.jar 和dt.jar 这两个包。...
  • 操作步骤1、新建一个文件夹xxx,将要执行java程序(可使用eclipse导出的可执行的jar包)拷贝到该文件夹中;2、将jdk中jre文件夹拷贝到要执行的java程序所在的文件夹;3、在java程序所在的文件夹中新建一个bat文件。bat...
  • 我一直试图在我的Mac上打开一个JAR文件但没有成功.它说无法打开JAR文件并要求我在控制台中查找任何错误消息.这是控制台消息.我怀疑问题是在第一行本身,但我不是来自软件背景,所以不知道这是否足以让任何知道Java的人...
  • rt.jar代表运行时JAR,包含引导程序类,我的意思是Core Java API中的所有类。我发现许多Java程序员都不知道rt.jar是什么?并经常与rt.jar文件的角色或为什么我们在Java中使用rt.jar文件混淆?毫不奇怪,这个名字有点...
  • java -jar MyJar.jar arg0 arg1 通过 -jar 参数可以直接运行,需要打 jar 包时,在 META-INF/MANIFEST.MF 文件里指定 Main-Class。关于这种打包操作参考 Maven 生成(打包)带有依赖的可以直接执行的一个 jar 包。 ...
  • 1:检查路径是否有错误:不要有中文,特殊字符等,推荐在jar包目录下shift+右键进入命令行 2:cmd是否有管理员权限? 3:检查jar包名称,是否有特殊字符
  • 【实例简介】selenium及所有依赖jar包(java),selenium,java,模拟浏览器,模拟登录【实例截图】【核心代码】selenium-jars├── cglib-nodep-2.1_3.jar├── commons-codec-1.9.jar├── commons-collections-...
  • 我安装了JDK和JRE。path系统变量更新为jdk bin文件夹的路径C:\程序文件\...pathPATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\oracle\product\12.2.0\client_1\bin;C:\Windows\system32;C:\W...
  • 工作涉及需要将jar包封装成小工具,用于解析数据文件并生成数据文件。 在工作电脑或者idea编译器中,运行正常。 但是使用个别电脑,会报错内存不足...java -jar-Xmn128m -Xms512m -Xmx512m Demo.jar 问题解决。 ...
  • java代码执行时完全没问题,但是打成jar包执行时,出现了空指针异常!!! java代码执行时: jar包执行时: 原因是获取项目路径的问题,我把Excel文件和java文件放在了同一级别中 使用getProperty(“user.dir”)...
  • jar包先进行解压。 class文件是java文件编译后产生的一个文件,class文件便于在软件上运行,但是我们无法阅读中间的程序,所以我们需要将class文件转换成java文件。 1.首先要个工具: jad.exe 要的可以到这里找...
  • jar包运行时报:java.lang.unsatisfiedlinkerror:Unable to load library ‘dhnetsdk’ ‘libdhnetsdk.so’:无法共享与打开目录。 jar有调用第三方的SDK; jar包之前是运行在windows服务上,有调用.dll文件; 后需要...
  • 1、窗口被锁定,可按CTRL + C打断程序运行,关闭窗口程序停止运行java -jar XXX.jar2、窗口不被锁定,关闭窗口时,程序停止运行java -jar XXX.jar &3、nohup 意思是不挂断运行,当账户退出或终端关闭时,程序仍然...
  • Java exec jar

    2021-02-25 20:29:13
    今天在学习的Maven的时候需要执行Maven构建出来的jar文件是否正确,故需要执行该jar文件看看运行结果是否正确。Maven工程的目录结果如下: Eclipse的工作目录在E:\workspace\EX11下,如下图所示: Maven构建的jar...
  • java如何生成jar

    2021-02-12 12:25:39
    将*.class文件压缩成一个文件交付给用户使用,那么这样的文件就称为jar文件。如果要想生成jar文件,直接使用JDK中bin目录里的jar.exe就可以将所有的类文件进行压缩。此命令是随JDK一起安装的,直接在命令行中输入jar...
  • Javajar命令详解

    千次阅读 2021-04-21 21:32:43
    笔者了解到jarjava archive file 的简写。从名字就可以知道,它的应用与Java息息相关。下面就详细介绍如何自己生成jar包,这样我们管理我们自己的代码(尤其是一些比较重要而且不会或者很少有修改的代码)。安装好JDK...
  • 开发一个演示项目项目源代码开发项目名称叫jar-package-example(其实只是一个文件夹, 用以将演示的所有文件夹和文件存放在其中, 没啥其它作用), 为了方便, 后文统一叫jar-package-example目录为项目根目录....
  • 背景现在很多软件都支持集群部署,但是测试环境通常资源有限,所以一般通过单台机器模拟集群部署(使用不同端口,运行相同jar包),本文的目的就是通过多种方式实现此需求。两个程序1、jar程序①springboot程序②只...
  • 1、Java项目生成jar包(1)、“项目”右键->"Export..."导出,弹出“导出设置”窗口如下:(2)、选择要打包的文件,如下图:(3)、设置导出的提示信息,如下图:(4)、指定程序入口,如图:(5)、查看结果,如图:2、...
  • java jar打包命令使用

    2021-03-05 23:48:01
    用法:jar {ctxu}[vfm0Mi] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...选项:-c 创建新的存档-t 列出存档内容的列表-x 展开存档中的命名的(或所有的〕文件-u 更新已存在的存档-v 生成详细输出到标准输出上-f ...
  • javajar 命令运行Jar

    千次阅读 2021-02-28 17:16:29
    学会如何写一段转换jar包的程序,将你的jar包转换成你能使用javajar 命令运行jar包或象在windows系统上那样通过双击来运行jar包。你可以很容易地将一个应用的所有的类和资源打包到一个jar文件中去。事实上,这只是...
  • Java 打包成jar包 和 解压jar

    千次阅读 2021-03-08 03:42:07
    解压jarjar xf xxx.jar打包成jar包方法一:通过jar命令jar命令的用法:下面是jar命令的帮助说明:用法:jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...选项包括:-c 创建新的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,342,707
精华内容 537,082
关键字:

jarjava

java 订阅