草庐IT

Android——最简单的 JS H5 交互

PlayfulKing 2023-04-03 原文

安卓 与 Web JS 交互的操作,其实网上一搜,教程案例都已经满大街了,但GT库还是向 Web JS 交互出手了,要问为啥,因为博主是个懒鬼,不想写太多代码,其实我们都知道 原版的WebView 是有很多问题的,内存泄露,数据安全性,Js不友好支持等等一些列问题,都要自己去手动编码置解决,GT库 封装好的Web 避了很多原版 Web的许多坑,博主不想以后每次用到 Js 交互都写一套,而且博主自己在用了封装好的 JS 交互后,简直不要太爽。忍不住要和家人们分享,嘿嘿。

GT库依旧保持简易开发扩展性开发 ,在浅浅的开发功能上可以直接使用,在想深入开发时可以有较好的扩展,尽量少写代码。

目录

 使用GT库里的,当然需要先依赖好GT库啦:

 Html代码:demo.html

activity_main.xml布局:

WebViews.java 代码(核心)

MainActivity.java 代码 (如何使用WebViews)

咋们再来从 WebViews 类中多加一些方法:

这次里面增加了这些方法:

GT库 JS 交互 高级用法:

1.查找元素: 查到到具体元素后进行其他操作

2.设置/替换 参数

3.隐藏/显示

4.设置 单击事件/单击链接

设置单击跳转链接:

设置单击调用 Js 方法并传参:

设置单击调用 Android 暴露的方法并传参:

万能JS 交互 API:


 使用GT库里的,当然需要先依赖好GT库啦:

GitHub - 1079374315/GTContribute to 1079374315/GT development by creating an account on GitHub.https://github.com/1079374315/GT

好了,咋们直接上效果图:(为了保证逻辑不复杂,博主已经非常简了)

效果图已经很明了的展现了 Android 与 网页的交互了,双方互发消息与互接收消息,接下来咋们来看看代码:

 Html代码:demo.html

<html>
    <head>
        <meta charset="utf-8">
        <title>最简单的JS交互</title>
        <script>
            //读取安卓传递过来的数据并弹窗
            function readData(json){
              alert("读取到安卓数据:" + json)
            }
            //发送消息给安卓
            function sendData(){
               var appData = "2023年";
               com_zuanuniverse_myapplication_WebViews.sendH5Data(appData)
            }
        </script>
    </head>
    <body>
        <button onclick="sendData()">发送json信息</button>
    </body>
</html>

够简单吧!两个方法,一个是读取方法,一个是 单击Web按钮发送方法。

咋们再看看安卓这边代码:

activity_main.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <!-- Web 容器 -->
    <RelativeLayout
        android:id="@+id/rl"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#D19898"
        app:layout_constraintDimensionRatio="h,1:1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送数据到 Web"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/rl"
        app:layout_constraintVertical_bias="0.066" />

</androidx.constraintlayout.widget.ConstraintLayout>

WebViews.java 代码(核心)

public class WebViews extends GT.GT_WebView.AnnotationWebView {

    //必须要写的
    public WebViews(Context context, ViewGroup viewGroup) {
        super(context, viewGroup);
    }

    //读取 Web 传递过来的数据
    @Override
    public void readData(String json) {
        super.readData(json);
        GT.toast(context, "读取到 JS 发送的消息:" + json);//使用吐司显示
        //这里建议与H5通讯使用 json 通讯,可以根据不同的 code编号 类型来处理不同的业务逻辑,
        // 实在不能满足需求才使用暴露方法给H5,一般与H5商量好通讯协议,大多数逻辑都能完成的。
    }
}

核心代码在这,集成GT库封装好的 AnnotationWebView 类,在重写 readData 方法进行读取数据,读取到后进行用吐司显示。看完是不是很神奇,一般想要接收到 H5 发送过来的数据需要用注解@JavascriptInterface 标识才能收到数据,但这里直接重写 readData 就能收到数据,那是因为GT库都帮咋们封装好了。让开发者只要专心与业务逻辑不操心数据传递的等等。

MainActivity.java 代码 (如何使用WebViews)

public class MainActivity extends AppCompatActivity {

    private WebViews webView;
    private RelativeLayout rl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rl = findViewById(R.id.rl);//获取网页容器
        webView = new WebViews(this, rl);//初始化 WebViews 并设置好WebView 容器
        webView.loadAsset("demo.html");//本地调试地址

        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                webView.sendAndroidData("2022年");//发送了数据给 Web
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        webView.finish();//会自动释放资源
    }
}

写到这里就可以直接允许测试了,实例化 WebViews 并设置扔进容器里,一个安卓按钮单击后向 H5 发送数据,够简单吧~

而且只要在发送的后面加一个接口,就可以直接接收到 H5 处理过后的数据:

findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //发送了数据给 Web
                webView.sendAndroidData(25, new GT.OnListener<String>() {
                    @Override
                    public void onListener(String... obj) {
                        GT.logt("经过H5处理过的数据:" + obj[0]);
                    }
                });
            }
        });

然后 Html 也要增加一个处理逻辑:(就是简单的将 25 * 2 返回给安卓)

<html>
    <head>
        <meta charset="utf-8">
        <title>最简单的JS交互</title>
        <script>
                //读取安卓传递过来的数据并弹窗
                function readData(json){
                  alert("读取到安卓数据:" + json)
                  return json * 2;
                }
                //发送消息给安卓
                function sendData(){
                   var appData = "2023年";
                   com_zuanuniverse_myapplication_WebViews.sendH5Data(appData)
                }
            </script>
    </head>
    <body>
    <button onclick="sendData()">发送json信息</button>
    </body>
</html>

看到这个,搞过 安卓 JS 交互的童靴们就会有个疑惑,

文中的 H5 通过 com_zuanuniverse_myapplication_WebViews.sendH5Data(appData)发送数据给安卓,那这段 com_zuanuniverse_myapplication_WebViews 是从哪里获取的呢?

答案是:从 WebViews 类中获取。

咋们再来从 WebViews 类中多加一些方法:

public class WebViews extends GT.GT_WebView.AnnotationWebView {

    //必须要写的
    public WebViews(Context context, ViewGroup viewGroup) {
        super(context, viewGroup);
    }

    //如果没需要监听网页加载进度的功能,该方法可以不写
    @Override
    public void loadProgress(int progress) {
        super.loadProgress(progress);
        GT.logt("progress:" + progress);//网页加载进度条
    }

    //如果没需要初始化的东西,该方法可以不写
    @Override
    protected void initView(Context context, WebView webView) {
        super.initView(context, webView);
        // 该参数 jsToAndroidName 是属于封装类里的,无法修改仅仅用来提供给 H5开发者
         GT.logt("与H5通讯的对象:" + jsToAndroidName);

    }

    //读取 Web 传递过来的数据
    public void readData(String json) {
        super.readData(json);
        GT.logt("读取到 JS 发送的消息:" + json);
        //这里建议与H5通讯使用 json 通讯,可以根据不同的 code编号 类型来处理不同的业务逻辑,
        // 实在不能满足需求才使用暴露方法给H5,一般与H5商量好通讯协议,大多数逻辑都能完成的。
    }

    //暴露给 H5 自动获取登录信息
    @JavascriptInterface
    public String getUserId() {
        return "userId = 666";
    }

    //如果没需要初始化的东西,该方法可以不写
    @Override
    public void onDestroy() {
        super.onDestroy();
        GT.logt("Web已被销毁");
    }
}

这次里面增加了这些方法:

loadProgress(用于监听网页加载进度)、

initView(初始化业务逻辑东西)、

getUserId(暴露给H5调用的方法)、

onDestroy(监听销毁方法),

而其中的 jsToAndroidName 参数就是专门提供给 H5 开发者使用的对象参数

运行日志:

 新增的方法中,有一个暴露给H5 调用的方法的,这个H5那边咋使用呢

咋们来改改 Html 代码

<html>
    <head>
        <meta charset="utf-8">
        <title>最简单的JS交互</title>
            <script>

                //调用安卓那边的 getUserId 方法来获取 安卓返回的值
                var userId =  com_zuanuniverse_myapplication_WebViews.getUserId();
                alert("主动获取的数据:" + userId)

                //读取安卓传递过来的数据并弹窗
                function readData(json){
                  alert("读取到安卓数据:" + json)
                }

                //发送消息给安卓
                function sendData(){
                   var appData = "2023年";
                   com_zuanuniverse_myapplication_WebViews.sendH5Data(appData)
                }

                //单击 按钮后获取 安卓暴露方法返回值
                function getUserId(){
                    var userId =  com_zuanuniverse_myapplication_WebViews.getUserId();
                    alert("按下按钮后 主动获取的数据:" + userId)
                }

            </script>
    </head>
    <body>
        <button onclick="sendData()">发送json信息</button>
        <br/>
        <button onclick="getUserId()">获取安卓信息</button>
    </body>
</html>

运行效果图:

 显示调用了主动调用的 getUserId 然后再单击按钮调用 getUserId 方法,再调用安卓的方法,这个暴露的使用方式与原生的使用是一样的,所以GT库封装对原生是有较好扩展性的。

当前,GT库封装的 WebView 还对加载其他类型的网页数据进行了兼容:

webView.loadWeb("https://blog.csdn.net/qq_39799899");//调用网络网页
webView.loadHtmlCode("");//加载富文本
webView.loadSdCard("");//加载SD卡路径的html

另外提供简易版 Json 格式,供伙伴们自定义编写:

{
    "code":1,
    "msg":"",
    "data":{
        "userId":0,
        "appData":"某某某类型"
    },
    "errorCode":""
}

GT库 JS 交互 高级用法:

具体功能就是对 H5 进行侵入式开发,啥叫侵入式开发?简单点就是说可以在安卓端动态修改 H5 代码,例如某某视频网站有个广告去不掉,咋们可以使用 H5 侵入式开发将 广告弹窗等元素,直接隐藏掉,或者替换成自己的广告图片,听起来很奈斯吧。

目前GT库封装的 API 仅仅涉及以下方面:

(今后需要或宝子们有需要可以私信我或评论区留言,博主后面加上)

1.查找元素
2.设置/替换 参数
3.隐藏/显示
4.设置 单击事件/单击链接

Html 演示代码:

<html>
<head>
    <meta charset="utf-8">
    <title>交互信息</title>

    <script>
            function aaa(value){
                 alert("value:" + value)
            }
    </script>
    
</head>

<body>
<div id="id_div" title="已加入 CSDN 5年" class="person-code-age" style="background-color:#C7E9FD;color:#1E68D8;" data-v-d1dbb6f8="">
    <img src="https://img-home.csdnimg.cn/images/20210108035952.gif" alt="" data-v-d1dbb6f8="">
    <span data-v-d1dbb6f8="">码龄5年</span>
</div> </br>

<a id="id_a" class="class_a" name="name_a" >A</a>

</body>
</html>

1.查找元素: 查到到具体元素后进行其他操作

 //Html 代码参考: <a id="id_a" class="class_a" name="name_a" >A</a>
 webView.findViewById("id_a");//根据元素 ID 查找元素

 webView.findViewByClassName("class_a");//根据元素 className属性 查找第1位元素
 webView.findViewByClassName("class_a",0);//根据元素 className属性 查找第1位 元素
 webView.findViewByClassNames("class_a");//根据元素 className属性 查找多位元素

 webView.findViewByName("name_a");//根据元素 Name属性 查找第1位元素
 webView.findViewByName("name_a",0);//根据元素 Name属性 查找第21位 元素
 webView.findViewByNames("name_a");//根据元素 Name属性 查找多位元素

 webView.findViewByTagName("a");//根据元素 a标签 查找第1位元素
 webView.findViewByTagName("a",0);//根据元素 a标签 查找第1位 元素
 webView.findViewByTagNames("a");//根据元素 a标签 查找多位元素
 /**
   //html 代码参考
   <script>          
     var myH1 = document.createElement("h1");
   </script>
 */
  webView.findViewByViewName("myH1");//根据自定义的 View变量名 查找元素

2.设置/替换 参数

效果图:

 具体执行代码:

    //webView 是 来自于集成实现 GT封装库的
    webView.beginTransaction();//开启事务 (必要的)

    //获取到 img 标签后替换 图片
    webView.findViewByTagName("img").setImgUrl("https://csdnimg.cn/identity/blog4.png");
    webView.findViewByTagName("span").setText("码龄100年");//修改a标签的 文本内容
    webView.findViewByTagName("span").setTextSize(18);//修改a标签的 文字大小
    webView.findViewByTagName("span").setTextColor("red");//修改a标签的 文字颜色

    //创建一个新的 图片元素
    webView.newImgView("myImg","https://profile.csdnimg.cn/7/5/9/1_qq_39799899");
    //获取到 a标签,并将新创建的 图片元素 添加到 a标签内
    webView.findViewById("id_a").addView("myImg");
    //并将新创建的 图片元素 添加到 body 内
    //webView.addBodyView("myImg");

    String commit = webView.commit();//提交事务 (必要的)
    GT.logt("查看最终执行的JS代码:" + commit);

3.隐藏/显示

效果图:

  具体执行代码:

    //webView 是 来自于集成实现 GT封装库的
    webView.beginTransaction();//开启事务 (必要的)
                
    //获取到 div 隐藏
    webView.findViewByTagName("div").setHide();
    //获取到 div 显示
    //webView.findViewByTagName("div").setShow();
    //自定义 隐藏元素属性
    //webView.findViewByTagName("div").setShowOrHide(true,"none");
                
    webView.commit();//提交事务 (必要的)

4.设置 单击事件/单击链接

设置单击监听 效果图:

 实现代码:

//单击安卓按钮
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //webView 是 来自于集成实现 GT封装库的
                webView.beginTransaction();//开启事务 (必要的)

                //获取到 a 标签元素后 设置单击事件监听
                webView.findViewById("id_a").setOnClickListener(new GT.OnListener() {
                    @Override
                    public void onListener(Object[] obj) {
                        GT.toast(MainActivity.this,"单击了 a 标签");//监听后弹出吐司
                    }
                });

                webView.commit();//提交事务 (必要的)

            }
        });

 够简单吧,但注意,一定一定一定不能在未加载完 Web 的情况下注册单击监听,必须必须要 Web完全加载完后才能注册单击事件

设置单击跳转链接:

效果图:

 实现代码:

//单击安卓按钮
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //webView 是 来自于集成实现 GT封装库的
                webView.beginTransaction();//开启事务 (必要的)

                //获取到 a 标签元素后 设置单击跳转链接
                webView.findViewById("id_a").setOnClickLink("https://blog.csdn.net/qq_39799899");

                webView.commit();//提交事务 (必要的)

            }
        });

设置单击调用 Js 方法并传参:

效果图:

 实现代码:

//单击安卓按钮
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //webView 是 来自于集成实现 GT封装库的
                webView.beginTransaction();//开启事务 (必要的)

                //获取到 a 标签元素后 设置单击调用 JS 的 aaa 方法,并传参过去
                webView.findViewById("id_a").setOnClickFunction("aaa('GT库调用JS成功!')");

                webView.commit();//提交事务 (必要的)

            }
        });

设置单击调用 Android 暴露的方法并传参:

效果图:

 实现代码: 给 a标签 设置单击就调用  WebViews 类里的 getTokenId 方法

public class WebViews extends GT.GT_WebView.AnnotationWebView {

    //必须要写的
    public WebViews(Context context, ViewGroup viewGroup) {
        super(context, viewGroup);
    }

    @JavascriptInterface
    public void getTokenId(String value) {
        GT.toast(context,"被Js触发了安卓方法成功:" + value);
    }

}

MainActivity代码:

//单击安卓按钮
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //webView 是 来自于集成实现 GT封装库的
                webView.beginTransaction();//开启事务 (必要的)

                //获取到 a 标签元素后 设置单击调用安卓暴露的 getTokenId 方法并传参
                webView.findViewById("id_a").setOnClickAndroidFunction("getTokenId('GT库数据')");

                webView.commit();//提交事务 (必要的)

            }
        });

够简单吧,这些就是GT库目前版本已经封装好的 API ,其实只要你会 JS 代码,其实就知道还有很多很多骚操作,但博主精力有限,目前 GT库 仅仅将最基础的 API 提供给宝子们,会JS 语言的如果觉得这里还不能满足你的邪恶,可以再用下面这个万能的 JS API 来实现邪恶的想法。

万能JS 交互 API:

效果图:

 实现代码:

//单击安卓按钮
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //webView 是 来自于集成实现 GT封装库的
                webView.beginTransaction();//开启事务 (必要的)

                //获取到 a 标签元素后 设置单击调用安卓暴露的 getTokenId 方法并传参
                webView.addJsCode(
                        "document.getElementById('id_a').onclick = function(){  alert('GT库不止这一个好用的功能哦!')  }; "
                );

                webView.commit();//提交事务 (必要的)

            }
        });

够简单吧,今后有改变,会接着在这篇文章下面添加的,该篇文章值得收藏哦,

感谢观看~

下篇再见~

点个关注点个赞呗(〃'▽'〃)   关注博主最新发布库:GitHub - 1079374315/GT

有关Android——最简单的 JS H5 交互的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  2. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  5. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  6. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  7. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  8. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  9. ruby - 使用 Ruby,计算 n x m 数组的每一列中有多少个 true 的简单方法是什么? - 2

    给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in

  10. ruby - 在 Ruby 中搜索大文件的更简单方法? - 2

    我正在编写一个简单的日志嗅探器,它将在日志中搜索表明我支持的软件存在问题的特定错误。它允许用户指定日志路径并指定他们想要搜索多少天前。如果用户关闭日志滚动,日志文件有时会变得非常大。目前我正在做以下事情(虽然还没有完成):File.open(@log_file,"r")do|file_handle|file_handle.eachdo|line|ifline.match(/\d+++-\d+-\d+/)etc...line.match显然会查找我们在日志中使用的日期格式,其余逻辑将在下面。但是,有没有更好的方法来搜索没有.each_line的文件?如果没有,我完全同意。我只是想确保我使

随机推荐