Android生成Java AIDL

AIDL:Android Interface Definition Language

AIDL是为了实现进程间通信而设计的Android接口语言

Android进程间通信有多种方式,Binder机制是其中最常见的一种

AIDL的本质就是基于对Binder的运用从而实现进程间通信

这篇博文从实战出发,用一个尽可能精简的Demo,实现两个App(也是两个进程:服务端mainapp、客户端otherapp)通过AIDL的跨进程通信

一.创建两个App


按照下列步骤先创建两个App:

(1).新建一个开发文件夹(本Demo中命名为aidl-test)

(2).使用AndroidStudio在aidl-test文件夹下创建第一个Empty Activity的空App:mainapp

为了后续方便起见

创建完成后,把Studio默认创建的MainActivity.java名字改一下,改成MainAppActivty.java

(3).创建第二个Empty Activity的空App:otherapp

两个空App创建完成了:

二.在mainapp中创建一个Service

上一节中新建了两个空App:mainappotherapp

现在就先在mainapp中实现一个service

使用方便又快捷的studio创建MainAppService.java

 

可以看到新建的MainAppService会自动实现一个onBind(Intent intent)方法,这个方法后续我会在其中进行代码实现,它需要在其他进程连接到Service时,返回一个继承了android.os.Binder的对象

先在 MainAppActivity 和 MainAppService 中添加一些必要的生命周期函数代码
再在 MainAppService 中添加:
onBind(Intent intent):被客户端绑定时执行
onUnbind(Intent intent):被客户端解绑时执行

@com/android/mainapp/MainAppActivity.java


package com.android.mainapp;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
 
public class MainAppActivity extends AppCompatActivity {
    private String TAG = "AIDL-MainAppActivity";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v(TAG, "onCreate()");
        setContentView(R.layout.activity_main);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy()");
    }
}
@com/android/mainapp/MainAppService.java 


package com.android.mainapp;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
 
public class MainAppService extends Service {
    private String TAG = "AIDL-MainAppService";
 
    public MainAppService() {
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
    }
 
    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart()");
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
 
    @Override
    public boolean onUnbind(Intent intent) {
        Log.v(TAG, "onUnbind()");
        return true;
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy()");
    }
}

三.mainapp中实现AIDL

依然使用方便又快捷的AndroidStudio在mainapp的main目录下创建一个名为IAppAidlInterface.aidl 的AIDL文件

 

AndroidStudio创建 IAppAidlInterface.aidl 会自动实现一个默认的可用于进程间传参通信的void basicTypes(...)函数,其参数是java的几种基础数据类型

除此之外,AIDL还支持多种其他数据类型:byte、short、char、charSequence、 List、 Map等

除了AndroidStudio自动创建的basicTypes(...)函数,我在AIDL文件里面再新增一个setData(..)函数,用于后面跨进程的数据传输,虽然使用AndroidStudio自动生成的basicTypes(...)也是可以的,但是自己创建一个函数会更具有代表性.

在本篇博文最开始就阐述过,AIDL的本质是对Binder的运用,从而实现进程间通信

那么现在Binder在哪呢?

IAppAidlInterface.aidl文件创建之后,build一下工程,AndroidStudio会在build目录下创建一个aidl_source_output_dir文件夹,同时在这个文件夹下创建与IAppAidlInterface.aidl包名、文件名相同的文件夹目录和java文件

IAppAidlInterface.java文件中通过继承android.os.Binder创建一个抽象的代理类stub,这个stub抽象代理类主要做如下几件事:

通过stub自身实例实现进程内部的通信
通过实现一个内部代理类Porxy用于跨进程通信
重写Binder中的onTransact()函数,实现AIDL接口文件中声明的函数进行数据传输
传输的数据必须是序列化的android.os.Parcel类型数据 

 

当然,如果项目需要对AIDL的Binder实现过程进行自定义封装,方便项目中对进程间通信机制进行定制化,那么,完全可以不采用AndroidStudio自动生成的IAppAidlInterface.java,只须要按照自己的需要实现IAppAidlInterface.java中对Binder进程间通信的实现过程就行了

因为归根结底,AIDL实现进程间通信的基础就是Binder机制,只要使用Binder实现AIDL进程间通信的目的就可以了

IAppAidlInterface.java就先讨论到这里,这篇博文主要是对AIDL的使用进行研究,其对Binder机制的实现与封装不在此做深入探讨

后续会专门开一篇博文讲解AIDL对Binder机制的内部实现,以及用户如何自定义封装

四.otherapp中也实现AIDL


上一节中,作为服务端的mainapp里创建了一个AIDL文件,客户端的otherapp中也需要实现一份相同的AIDL,要不然客户端就无法引用到了对应的函数和stub等了

很简单,把mainapp中的AIDL文件整个包名目录直接拷贝到otherapp中即可,然后再build一下工程

 

接下来,需要添加一些代码,实现客户端otherapp与服务端mainapp的相连

五.mainapp中添加代码


前文中已经展示过,MainAppService会随着MainAppActivity的onCreate()和onDestroy()生命周期startService()和stopService()

mainapp中要添加的代码在MainAppService.java中,需要在MainAppService中做下面一些事情:

  • 使用匿名内部类实现IAppAidlInterface.Stub抽象类,用于实现IAppAidlInterface.aidl中的接口函数和onBinder()时返回匿名内部类实例
  • onBinder()中启动一个线程,每1秒轮循接收客户端发送过来的数据

 这里提到个题外的知识点,Service中除了onBinder()函数外还有个onRebind()函数

      如果同一客户端每次unBindService()之后再bindService()并且发送的Intent也一样,那么onBind()就只会在服务端第一次被这个客户端连接时才执行,后续重连时都不会再执行了。

     而onRebind()在服务端第一次被连接时不会被执行,但是之后每次重连都会执行,不论Intent是否一样。

    如果想要onBind()在同一客户端连接时都能执行,客户端在每次bindService()时,改变发送Intent的type或其他成员变量就行了

定义一个string变量用于接收客户端传过来的字符串,定义一个boolean变量用于控制线程

AndroidMainfest.xml中为MainAppService添加Service标签

六.otherapp中添加代码

otherapp里面主要需要做如下几件事:

  • 新建一个Intent,用于连接服务端mainapp
    IntentComponent设置为Sevice的包名和类名
  • 新建两个button,用于控制bindService()绑定和unbindService()解绑
  • 重写Service连接和断开的两个基础函数onServiceConnected()onServiceDisconnected()
  • AndroidMainfest.xml中添加查询包名权限,以便otherapp可以查询到mainapp,或者直接指定查询mainapp的包名

 

七.运行、验证 

到此,一个最基础的使用AIDL实现两个App(服务端mainapp、客户端otherapp)之间通信的demo代码就完成了,下面我们来验证一下。

编译、安装apk:

项目build Apk后会生成两个apk,两个都install上

 

运行验证:

注:本demo中代码的所有日志TAG都加上了AIDL前缀,方便日志打印验证

先启动一下mainapp,MainAppService不会被启动但是会被注册到系统,因为在mainapp的AndroidMainfest.xml中对MainAppService进行了Service标签添加。

 

退出mainapp后,再打开otherapp:

现在执行几次"Bind Service"和"Unbind Service",就会看到如下日志打印:

好,通过这个精简Demo,初步实现了两个App通过AIDL的跨进程通信 

 

八.源代码

接下来逐一展示实现的源码

mainapp源码:

D:\Codes\aidl-test\app\src\main\aidl\com\android\mainapp\IAppAidlInterface.aidl

// IAppAidlInterface.aidl
package com.android.mainapp;
 
// Declare any non-default types here with import statements
 
interface IAppAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
 
    void setStringData(String strData);
}

 

D:\Codes\aidl-test\app\src\main\java\com\android\mainapp\MainAppActivity.java

package com.android.mainapp;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
 
public class MainAppActivity extends AppCompatActivity {
    private String TAG = "AIDL-MainAppActivity";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v(TAG, "onCreate()");
        setContentView(R.layout.activity_main);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy()");
    }
}

D:\Codes\aidl-test\app\src\main\java\com\android\mainapp\MainAppService.java

package com.android.mainapp;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
 
public class MainAppService extends Service {
    private String TAG = "AIDL-MainAppService";
 
    private String mStrData;
    private boolean mSetServiceRunning = true;
 
    public MainAppService() {
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        Log.v(TAG, "onStart()");
    }
 
    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart()");
    }
 
    IAppAidlInterface.Stub mStub = new IAppAidlInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
 
        }
 
        @Override
        public void setStringData(String strData) {
            mStrData = strData;
        }
    };
 
    @Override
    public IBinder onBind(Intent intent) {
        Log.v(TAG, "onBind()");
        mSetServiceRunning = true;
 
        new Thread() {
            @Override
            public void run() {
                super.run();
                while (mSetServiceRunning) {
                    try {
                        Thread.sleep(1000);
                        Log.v(TAG, "mStrData:"+mStrData);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
 
        return mStub;
    }
 
    @Override
    public boolean onUnbind(Intent intent) {
        Log.v(TAG, "onUnbind()");
        mSetServiceRunning = false;
        return true;
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy()");
    }
}

D:\Codes\aidl-test\app\src\main\AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
 
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Mainapp"
        tools:targetApi="31">
        <service
            android:name=".MainAppService"
            android:enabled="true"
            android:exported="true">
        </service>
 
        <activity
            android:name=".MainAppActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
 
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>
 
</manifest>

 

otherapp源码: 

D:\Codes\aidl-test\otherapp\src\main\aidl\com\android\mainapp\IAppAidlInterface.aidl

// IAppAidlInterface.aidl
package com.android.mainapp;
 
// Declare any non-default types here with import statements
 
interface IAppAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
 
    void setStringData(String strData);
}

D:\Codes\aidl-test\otherapp\src\main\java\com\android\otherapp\OtherAppMainActivity.java

package com.android.otherapp;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
 
import com.android.mainapp.IAppAidlInterface;
 
public class OtherAppMainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
    private String TAG = "AIDL-OtherAppActivity";
 
    private int mICount = 0;
    private Intent mServiceIntent;
    private IAppAidlInterface mBinder;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other_app_main);
 
        mServiceIntent = new Intent();
        mServiceIntent.setComponent(new ComponentName("com.android.mainapp", "com.android.mainapp.MainAppService"));
 
        findViewById(R.id.btnBindMainAppService).setOnClickListener(this);
        findViewById(R.id.btnUnBindMainAppService).setOnClickListener(this);
    }
 
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnBindMainAppService: {
                Log.v(TAG, "onClick():btnBindMainAppService");
                bindService(mServiceIntent, this, Context.BIND_AUTO_CREATE);
            }
            break;
 
            case R.id.btnUnBindMainAppService: {
                Log.v(TAG, "onClick():btnUnBindMainAppService");
                unbindService(this);
                mBinder = null;
            }
            break;
        }
    }
 
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        if (mBinder == null) {
            mBinder = IAppAidlInterface.Stub.asInterface(iBinder);
            mICount++;
            Log.v(TAG, "onServiceConnected() 第 " + mICount + " 次");
            try {
                String strData = "第" + mICount + "次连接Service成功!";
                mBinder.setStringData(strData);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
 
    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        Log.v(TAG, "onServiceDisconnected");
    }
}

 

D:\Codes\aidl-test\otherapp\src\main\res\layout\activity_other_app_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".OtherAppActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="OtherApp"/>
 
    <Button
        android:id="@+id/btnBindMainAppService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="Bind  Service" />
 
    <Button
        android:id="@+id/btnUnBindMainAppService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="UnBind Service" />
 
</LinearLayout>

D:\Codes\aidl-test\otherapp\src\main\AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 
    <!--<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>-->
    <queries>
        <package android:name="com.android.mainapp"/>
    </queries>
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Mainapp">
        <activity
            android:name=".OtherAppMainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
 
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>
 
</manifest>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/875287.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《深入浅出AI》前言知识:机器学习知识总结

&#x1f468;‍&#x1f4bb;面向对象&#xff1a; 本篇前言知识主要介绍机器学习&#xff0c;方便小白或AI爱好者学习基础知识。 &#x1f49a;友情提醒&#xff1a; 本文内容可能未能含概机器学习所有知识点&#xff0c;其他内容可以访问本人主页其他文章或个人博客&#xf…

【devops】devops-git之介绍以及日常使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

SealSuite 一站式 IT 管理与办公安全解决方案,助力出海企业夯实数字化底座

数字化办公时代&#xff0c;企业升级 IT 基础设施&#xff0c;已不再是选择题&#xff0c;而是必答题。 数字化办公时代&#xff0c;企业为何要升级 IT 基础设施&#xff1f; 随着时代变化与科技进步&#xff0c;人们的工作方式也发生了巨大变化。如今&#xff0c;远程办公、全…

算法导论 总结索引 | 第五部分 第二十四章:单源最短路径

1、在最短路径问题中&#xff0c;给定一个带权重的有向图 G (V, E) 和权重函数 w: E→R &#xff0c;该权重函数 将每条边映射到实数值的权重上。图中一条路径 p 〈v0, v1, …, vk〉 的权重 w(p) 是构成该路径的 所有边的权重之和&#xff1a; 定义从结点 u 到结点 v 的最短路…

电压跟随器的作用是什么?

电压跟随器&#xff08;也称为单位增益放大器、缓冲放大器和隔离放大器&#xff09;是一种电压增益为 1 的运算放大器电路。这意味着运算放大器不会对信号进行任何放大。 之所以称为电压跟随器&#xff0c;是因为输出电压直接跟随输入电压&#xff0c;即输出电压与输入电压相同…

测试工程师学历路径:从功能测试到测试开发

现在软件从业者越来越多&#xff0c;测试工程师的职位也几近饱和&#xff0c;想要获得竞争力还是要保持持续学习。基本学习路径可以从功能测试-自动化测试-测试开发工程师的路子来走。 功能测试工程师&#xff1a; 1、软件测试基本概念&#xff1a; 学习软件测试的定义、目的…

产品探秘|开物——面向AI原生和云原生网络研究的首选科研平台

在当今高速发展的信息技术领域&#xff0c;特别是对于那些致力于前沿科技探索与实践的高校而言&#xff0c;拥有一款能够支持复杂网络业务研究与开发的平台至关重要。开物™数据网络开发平台&#xff08;Data Network Development Platform&#xff0c;简称DNDP&#xff09;&am…

Marin说PCB之在CST软件中如何搭建两端子电容器--03

上期文章的结尾讲到的问题不知诸位大神们是否还记得&#xff1a;就是一颗新电容器的物料是否可以完全替换掉之前的Murata家的这个GRT033D70E105ME18物料&#xff1f; 小编我也看了私信有不少的人认为是可以替换掉的&#xff0c;原因是两个电容封装&#xff0c;容值都是一样的&a…

停止向供应商提供您的数据

组织管理其数据基础设施的方式正在发生重大转变。越来越多的公司认识到存储和计算分离的优势&#xff0c;从而获得更好的性能、成本节约和可扩展性。这一趋势是由 AI 和 ML 工作负载日益复杂所推动的&#xff0c;这些工作负载需要灵活、高性能的系统。Databricks 首席执行官 Al…

Java短信验证码

想利用java给用户发送短信的话&#xff0c;需要我们与电信、移动、联通三大巨头合作&#xff08;其实还有广电&#xff0c;但是比较少用&#xff09;&#xff0c;让它帮你发信息&#xff0c;当然直接与它合作显然是不现实的&#xff0c;所以我们要借助第三方的短信平台来替我们…

el-tree父子不互相关联时,手动实现全选、反选、子级全选、清空功能

el-tree父子不互相关联时&#xff0c;手动实现全选、反选、子级全选、清空功能 1、功能实现图示 2、实现思路 当属性check-strictly为true时&#xff0c;父子节点不互相关联&#xff0c;如果需要全部选中或选择某一节点下的全部节点就必须手动选择每个节点&#xff0c;十分麻…

什么是科技与艺术相结合的异形创意圆形(饼/盘)LED显示屏

在当今数字化与创意并重的时代&#xff0c;科技与艺术的融合已成为推动社会进步与文化创新的重要力量。其中&#xff0c;晶锐创显异形创意圆形LED显示屏作为这一趋势下的杰出代表&#xff0c;不仅打破了传统显示设备的形态束缚&#xff0c;更以其独特的造型、卓越的显示效果和广…

使用AI赋能进行软件测试-文心一言

1.AI赋能的作用 提高速度和效率缺陷预测与分析 2.AI互动指令格式--文心一言 角色、指示、上下文例子、输入、输出 a 直接问AI 针对以下需求&#xff0c;设计测试用例。 需求&#xff1a; 1、账号密码登录系统验证账号和密码的正确性。 验证通过,用户登录成功,进入个人中心;验…

无刷直流电动机的匝间绝缘测试优化

近年来&#xff0c;随着消费者对高效、快速干发需求的增加&#xff0c;高速电吹风逐渐成为市场的宠儿。高速电吹风的关键技术之一便是无刷直流电动机&#xff0c;其转速可以高达100,000转/分钟以上&#xff0c;电压为DC310V。相比传统电吹风&#xff0c;高速电吹风在效率和用户…

Prometheus 监控平台(Prometheus Monitoring Platform)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

灰光模块,彩光模块-介绍

1. 引用 知识分享系列一&#xff1a;5G基础知识-CSDN博客 5G前传的最新进展-CSDN博客 灰光和彩光_通信行业5G招标系列点评之二&#xff1a;一文读懂5G前传-光纤、灰光、彩光、CWDM、LWDM、MWDM...-CSDN博客 ADOP带你了解&#xff1a;CWDM、DWDM、MWDM、LWDM&#xff1a;快速…

ffmpeg实现视频的合成与分割

视频合成与分割程序使用 作者开发了一款软件&#xff0c;可以实现对视频的合成和分割&#xff0c;界面如下&#xff1a; 播放时&#xff0c;可以选择多个视频源&#xff1b;在选中“保存视频”情况下&#xff0c;会将多个视频源合成一个视频。如果只取一个视频源中一段视频…

jmeter之TPS计算公式

需求&#xff1a; 如何确定环境当中的TPS指标 PV:&#xff08;Page View&#xff09;即页面访问量&#xff0c;每打开一次页面PV计数1&#xff0c;刷新页面也是。PV只统计页面访问次 数。 UV(Unique Visitor),唯一访问用户数&#xff0c;用来衡量真实访问网站的用户数量。 一般…

基于matlab交通标志识别系统用的APP designer设计的gui界面 交互原理:bp神经网络-训练好图像处理有灰度化-二值化-颜色区域定位识别

基于MATLAB的交通标志识别系统是一个实用的工具&#xff0c;用于识别道路交通标志。该系统结合了图像处理技术和BP神经网络模型&#xff0c;可以在给定的图像中定位并识别交通标志。通过使用MATLAB的App Designer工具&#xff0c;系统还提供了一个交互式的图形用户界面&#xf…

OpenAI发布o1大模型,突破LLM推理极限,弥补了之前在数学、科学和代码方面的不足

在北京时间9月13日凌晨&#xff0c;OpenAI正式发布了一系列全新的AI大模型【o1-preview 和 o1-mini】&#xff0c;专门针对复杂问题的解决。这一发布标志着一次重要的突破&#xff0c;新模型能够实现复杂的推理能力&#xff0c;通用模型在解决科学、代码和数学等领域中的难题方…