android开发最佳实践手册全网独一份,知名大企都在用,建议收藏(安卓开发实践)-ag凯发k8国际

  • 前言
  • 摘要
  • androids sdk
  • 构建系统
  • 工程总结
  • gradle 配置
  • ide集成开发环境和文本编辑器
  • 类库
  • activities and fragments
  • java 包结构
  • 测试框架
  • 模拟器
  • 混淆配置

本文是futurice公司的android开发人员总结的最佳实践,遵循这些准则可以避免重复制造轮子。如果你对ios或者windows phone开发感兴趣,那么也请看看ios最佳实践和windows客户端开发最佳实践。

  • 使用 gradle 和它推荐的工程结构
  • 把密码和敏感数据放在gradle.properties
  • 不要自己写 http 客户端,使用volley或okhttp库
  • 使用jackson库解析json数据
  • 避免使用guava同时使用一些类库来避免65k method limit(一个android程序中最多能执行65536个方法)
  • 使用 fragments来呈现ui视图
  • 使用 activities 只是为了管理 fragments
  • layout 布局是 xmls代码,组织好它们
  • 在layoutout xmls布局时,使用styles文件来避免使用重复的属性
  • 使用多个style文件来避免单一的一个大style文件
  • 保持你的colors.xml 简短dry(不要重复自己),只是定义调色板
  • 总是使用dimens.xml dry(不要重复自己),定义通用常数
  • 不要做一个深层次的viewgroup
  • 在使用webviews时避免在客户端做处理,当心内存泄露
  • 使用robolectric单元测试,robotium 做ui测试
  • 使用genymotion 作为你的模拟器
  • 总是使用proguard 和 dexguard混淆来项目

将你的android sdk放在你的home目录或其他应用程序无关的位置。 当安装有些包含sdk的ide的时候,可能会将sdk放在ide同一目录下,当你需要升级(或重新安装)ide或更换的ide时,会非常麻烦。 此外,若果你的ide是在普通用户,不是在root下运行,还要避免吧sdk放到一下需要sudo权限的系统级别目录下。

你的默认编译环境应该是gradle. ant 有很多限制,也很冗余。使用gradle,完成以下工作很方便:

  • 构建app不同版本的变种
  • 制作简单类似脚本的任务
  • 管理和下载依赖
  • 自定义秘钥
  • 更多

同时,android gradle插件作为新标准的构建系统正在被google积极的开发。

有两种流行的结构:老的ant & eclipse adt 工程结构,和新的gradle & android studio 工程结构, 你应该选择新的工程结构,如果你的工程还在使用老的结构,考虑放弃吧,将工程移植到新的结构。

老的结构

新的结构

主要的区别在于:

  • 新的结构明确的分开了'source sets' (main,androidtest),gradle的一个理念。 你可以做到,例如,添加源组‘paid’和‘free’在src中,这将成为您的应用程序的付费和免费的两种模式的源代码。
  • 你的项目引用第三方项目库时(例如,library-foobar),拥有一个顶级包名app从第三方库项目区分你的应用程序是非常有用的。 然后settings.gradle不断引用这些库项目,其中app/build.gradle可以引用。

常用结构 参考

google's guide on gradle for android

小任务 除了(shell, python, perl, etc)这些脚本语言,你也可以使用gradle 制作任务。 更多信息请参考gradle's documentation。

密码 在做版本release时你app的

build.gradle你需要定义 signingconfigs.此时你应该避免以下内容:

不要做这个 . 这会出现在版本控制中。

signingconfigs { release { storefile file("myapp.keystore") storepassword "password123" keyalias "thekey" keypassword "password789" }}

而是,建立一个不加入版本控制系统的gradle.properties文件。

keystore_password=password123key_password=password789

那个文件是gradle自动引入的,你可以在buld.gradle文件中使用,例如:

signingconfigs { release { try { storefile file("myapp.keystore") storepassword keystore_password keyalias "thekey" keypassword key_password } catch (ex) { throw new invaliduserdataexception("you should define keystore_password and key_password in gradle.properties.") } }}

使用 maven 依赖方案代替使用导入jar包方案 如果在你的项目中你明确使用率 jar文件,那么它们可能成为永久的版本,如2.1.1.下载jar包更新他们是很繁琐的, 这个问题maven很好的解决了,这在android gradle构建中也是推荐的方法。你可 以指定版本的一个范围,如2.1. ,然后maven会自动升级到制定的最新版本,例如:

dependencies { compile 'com.netflix.rxjava:rxjava-core:0.19. ' compile 'com.netflix.rxjava:rxjava-android:0.19. ' compile 'com.fasterxml.jackson.core:jackson-databind:2.4. ' compile 'com.fasterxml.jackson.core:jackson-core:2.4. ' compile 'com.fasterxml.jackson.core:jackson-annotations:2.4. ' compile 'com.squareup.okhttp:okhttp:2.0. ' compile 'com.squareup.okhttp:okhttp-urlconnection:2.0. '}

  • 无论使用什么编辑器,一定要构建一个良好的工程结构 编辑器每个人都有自己的 选择,让你的编辑器根据工程结构和构建系统运作,那是你自己的责任。
  • 当下首推android studio,因为他是由谷歌开发,最接近gradle,默认使用最新的工程结构,已经到beta阶段 (目前已经有release 1.0了),它就是为android开发定制的。
  • 你也可以使用eclipse adt ,但是你需要对它进行配置,因为它使用了旧的工程结构 和ant作为构建系统。你甚至可以使用纯文版编辑器如vim,sublime text,或者emacs。如果那样的话,你需要使用gardle和adb命令行。
  • 如果使用eclipse集成gradle 不适合你,你只是使用命令行构建工程,或迁移到android studio中来吧。
  • 无论你使用何种开发工具,只要确保gradle和新的项目结构保持官方的方式构建应用程序,避免你的编辑器配置文件加入到版本控制。
  • 例如,避免加入ant build.xml文件。 特别如果你改变ant的配置,不要忘记保持build.gradle是最新和起作用的。同时,善待其他开发者,不要强制改变他们的开发工具和偏好。

jackson 是一个将java对象转换成json与json转化java类的类库。gson 是解决这个问题的流行方案,然而我们发现jackson更高效,因为它支持替代的方法处理json:流、内存树模型,和传统json-pojo数据绑定。不过,请记住, jsonkson库比起gson更大,所以根据你的情况选择,你可能选择gson来避免app 65k个方法限制。其它选择: json-smart and boon json

网络请求,缓存,图片 执行请求后端服务器,有几种交互的ag凯发k8国际的解决方案,你应该考虑实现你自己的网络客户端。使用volley 或retrofit。volley 同时提供图片缓存类。若果你选择使用retrofit,那么考虑使用picasso 来加载图片和缓存,同时使用okhttp作为高效的网络请求。retrofit,picasso和okhttp都是有同一家公司开发(注: 是由square 公司开发),所以它们能很好的在一起运行。okhttp 同样可以和volley在一起使用 volley.

rxjava 是函数式反应性的一个类库,换句话说,能处理异步的事件。 这是一个强大的和有前途的模式,同时也可能会造成混淆,因为它是如此的不同。 我们建议在使用这个库架构整个应用程序之前要谨慎考虑。 有一些项目是使用rxjava完成的,如果你需要帮助可以跟这些人取得联系: timo tuominen, olli salonen, andre medeiros, mark voit, antti lammi, vera izrailit, juha ristolainen. 我们也写了一些博客: [1], [2], [3], [4].

如若你之前有使用过rx的经历,开始从api响应应用它。 另外,从简单的ui事件处理开始运用,如单击事件或在搜索栏输入事件。 若对你的rx技术有信心,同时想要将它应用到你的整体架构中,那么请在复杂的部分写好javadocs文档。 请记住其他不熟悉rxjava的开发人员,可能会非常难理解整个项目。 尽你的的全力帮助他们理解你的代码和rx。

retrolambda 是一个在android和预jdk8平台上的使用lambda表达式语法的java类库。 它有助于保持你代码的紧凑性和可读性,特别当你使用如rxjava函数风格编程时。 使用它时先安装jdk8,在android studio工程结构对话框中把它设置成为sdk路径,同时设置java8_home和java7_home环境变量, 然后在工程根目录下配置 build.gradle:

dependencies { classpath 'me.tatarka:gradle-retrolambda:2.4. '}

同时在每个module 的build.gradle中添加

apply plugin: 'retrolambda'android { compileoptions { sourcecompatibility javaversion.version_1_8 targetcompatibility javaversion.version_1_8}retrolambda { jdk system.getenv("java8_home") oldjdk system.getenv("java7_home") javaversion javaversion.version_1_7}

android studio 提供java8 lambdas表带是代码提示支持。如果你对lambdas不熟悉,只需参照以下开始学习吧:

  • 任何只包含一个接口的方法都是"lambda friendly"同时代码可以被折叠成更紧凑的语法
  • 如果对参数或类似有疑问,就写一个普通的匿名内部类,然后让android status为你生成一个lambda。
  • 当心dex方法数限制,同时避免使用过多的类库 android apps,当打包成一个dex文件时,有一个65535个应用方法强硬限制[1] [2] [3]。 当你突破65k限制之后你会看到一个致命错误。因此,使用一个正常范围的类库文件,同时使用dex-method-counts 工具来决定哪些类库可以再65k限制之下使用,特别的避免使用guava类库,因为它包含超过13k个方法。

fragments应该作为你实现ui界面默认选择。你可以重复使用fragments用户接口来 组合成你的应用。我们强烈推荐使用fragments而不是activity来呈现ui界面,理由如下:

  • 提供多窗格布局ag凯发k8国际的解决方案

fragments 的引入主要将手机应用延伸到平板电脑,所以在平板电脑上你可能有a、b两个窗格,但是在手机应用上a、b可能分别充满 整个屏幕。如果你的应用在最初就使用了fragments,那么以后将你的应用适配到其他不同尺寸屏幕就会非常简单。

  • 屏幕间数据通信

从一个activity发送复杂数据(例如java对象)到另外一个activity,android的api并没有提供合适的方法。不过使用fragment,你可以使用 一个activity实例作为这个activity子fragments的通信通道。即使这样比activity与activity间的通信好,你也想考虑使用event bus架构,使用如 otto 或者 greenrobot eventbus作为更简洁的实现。 如果你希望避免添加另外一个类库,rxjava同样可以实现一个event bus。

  • fragments 一般通用的不只有ui

你可以有一个没有界面的fragment作为activity提供后台工作。 进一步你可以使用这个特性来创建一个fragment 包含改变其它fragment的逻辑 而不是把这个逻辑放在activity中。

  • 甚至actionbar 都可以使用内部fragment来管理

你可以选择使用一个没有ui界面的fragment来专门管理actionbar,或者你可以选择使用在每个fragment中 添加它自己的action 来作为父activity的actionbar.参考.

很不幸,我们不建议广泛的使用嵌套的fragments,因为 有时会引起matryoshka bugs。我们只有当它有意义(例如,在水平滑动的viewpager在 像屏幕一样fragment中)或者他的确是一个明智的选择的时候才广泛的使用fragment。

在一个架构级别,你的app应该有一个顶级的activity来包含绝大部分业务相关的fragment。你也可能还有一些辅助的activity ,这些辅助的activity与主activity 通信很简单限制在这两种方法 intent.setdata() 或 intent.setaction()或类似的方法。

  • android 应用程序在架构上大致是java中的model-view-controller结构。 在android 中 fragment和activity通常上是控制器类(http://www.informit.com/articles/article.aspx?p=2126865). 换句话说,他们是用户接口的部分,同样也是views视图的部分。
  • 正是因为如此,才很难严格的将fragments (或者 activities) 严格的划分成 控制器controlloers还是视图 views。 最好还是将它们放在自己单独的 fragments 包中。只要你遵循之前提到的建议,activities 则可以放在顶级目录下。 若果你规划有2到3个以上的activity,那么还是同样新建一个activities包吧。
  • 然而,这种架构可以看做是另一种形式的mvc, 包含要被解析api响应的json数据,来填充的pojo的models包中。 和一个views包来包含你的自定义视图、通知、导航视图,widgets等等。 适配器adapter是在数据和视图之间。然而他们通常需要通过getview()方法来导出一些视图, 所以你可以将adapters包放在views包里面。
  • 一些控制器角色的类是应用程序级别的,同时是接近系统的。 这些类放在managers包下面。 一些繁杂的数据处理类,比如说"dateutils",放在utils包下面。 与后端交互负责网络处理类,放在network包下面。
  • 总而言之,以最接近用户而不是最接近后端去安排他们。

com.futurice.project├─ network├─ models├─ managers├─ utils├─ fragments└─ views ├─ adapters ├─ actionbar ├─ widgets └─ notifications

  • 命名 遵循前缀表明类型的习惯,形如type_foo_bar.xml。例如:fragment_contact_details.xml,view_primary_button.xml,activity_main.xml.
  • 组织布局文件 若果你不确定如何排版一个布局文件,遵循一下规则可能会有帮助。
  • 每一个属性一行,缩进4个空格
  • android:id 总是作为第一个属性
  • android:layout_**** 属性在上边
  • style 属性在底部
  • 关闭标签/>单独起一行,有助于调整和添加新的属性
  • 考虑使用

designtime attributes 设计时布局属性,android studio已经提供支持,而不是硬编码android:text (译者注:墙内也可以参考stormzhang的这篇博客链接)。

作为一个经验法则,android:layout_****属性应该在 layout xml 中定义,同时其它属性android:**** 应放在 styler xml中。此规则也有例外,不过大体工作 的很好。这个思想整体是保持layout属性(positioning, margin, sizing) 和content属性在布局文件中,同时将所有的外观细节属性(colors, padding, font)放 在style文件中。

例外有以下这些:

  • android:id 明显应该在layout文件中
  • layout文件中android:orientation对于一个linearlayout布局通常更有意义
  • android:text 由于是定义内容,应该放在layout文件中
  • 有时候将android:layout_width 和 android:layout_height属性放到一个style中作为一个通用的风格中更有意义,但是默认情况下这些应该放到layout文件中。

使用styles 几乎每个项目都需要适当的使用style文件,因为对于一个视图来说有一个重复的外观是很常见的。 在应用中对于大多数文本内容,最起码你应该有一个通用的style文件,例如:

应用到textview 中:

你或许需要为按钮控件做同样的事情,不要停止在那里。将一组相关的和重复android:****的属性放到一个通用的style中。

将一个大的style文件分割成多个文件 你可以有多个styles.xml 文件。android sdk支持其它文件,styles这个文件名称并没有作用,起作用的是在文件 里xml的`标签。因此你可以有多个style文件styles.xml,style_home.xml,style_item_details.xml,styles_forms.xml。 不用于资源文件路径需要为系统构建起的有意义,在res/values`目录下的文件可以任意命名。

colors.xml是一个调色板 在你的colors.xml文件中应该只是映射颜色的名称一个rgba值,而没有其它的。不要使用它为不同的按钮来定义rgba值。

不要这样做

#ffffff #2a91bd #5f5f5f #939393 #ffffff #ff9d2f#323232

使用这种格式,你会非常容易的开始重复定义rgba值,这使如果需要改变基本色变的很复杂。同时,这些定义是跟一些环境关联起来的,如button或者comment, 应该放到一个按钮风格中,而不是在color.xml文件中。

相反,这样做:

#ffffff #dbdbdb #939393 #5f5f5f #323232 #27d34d #2a91bd #ff9d2f #ff432f

向应用设计者那里要这个调色板,名称不需要跟"green", "blue", 等等相同。 "brand_primary", "brand_secondary", "brand_negative" 这样的名字也是完全可以接受的。 像这样规范的颜色很容易修改或重构,会使应用一共使用了多少种不同的颜色变得非常清晰。 通常一个具有审美价值的ui来说,减少使用颜色的种类是非常重要的。

像对待colors.xml一样对待dimens.xml文件 与定义颜色调色板一样,你同时也应该定义一个空隙间隔和字体大小的“调色板”。 一个好的例子,如下所示:

22sp 18sp 15sp 12sp 40dp 24dp 14dp 10dp 4dp 60dp 40dp 32dp

布局时在写 margins 和 paddings 时,你应该使用spacing_****尺寸格式来布局,而不是像对待string字符串一样直接写值。 这样写会非常有感觉,会使组织和改变风格或布局是非常容易。

避免深层次的视图结构 有时候为了摆放一个视图,你可能尝试添加另一个linearlayout。你可能使用这种方法解决:

即使你没有非常明确的在一个layout布局文件中这样使用,如果你在java文件中从一个view inflate(这个inflate翻译不过去,大家理解就行) 到其他views当中,也是可能会发生的。

可能会导致一系列的问题。你可能会遇到性能问题,因为处理起需要处理一个复杂的ui树结构。 还可能会导致以下更严重的问题stackoverflowerror.

因此尽量保持你的视图tree:学习如何使用relativelayout, 如何 optimize 你的布局 和如何使用 “ 标签.

小心关于webviews的问题. 如果你必须显示一个web视图, 比如说对于一个新闻文章,避免做客户端处理html的工作, 最好让后端工程师协助,让他返回一个 "纯" html。 webviews 也能导致内存泄露 当保持引他们的activity,而不是被绑定到applicationcontext中的时候。 当使用简单的文字或按钮时,避免使用webview,这时使用textview或buttons更好。

android sdk的测试框架还处于初级阶段,特别是关于ui测试方面。android gradle 目前实现了一个叫connectedandroidtest的测试, 它使用一个junit 为android提供的扩展插件 extension of junit with helpers for android.可以跑你生成的junit测试,

只当做单元测试时使用 robolectric ,views 不用 它是一个最求提供"不连接设备的"为了加速开发的测试, 非常时候做 models 和 view models 的单元测试。 然而,使用robolectric测试时不精确的,也不完全对ui测试。 当你对有关动画的ui元素、对话框等,测试时会有问题, 这主要是因为你是在 “在黑暗中工作”(在没有可控的界面情况下测试)

_robotium 使写ui测试非常简单。 _ 对于ui测试你不需 robotium 跑与设备连接的测试。 但它可能会对你有益,是因为它有许多来帮助类的获得和分析视图,控制屏幕。 测试用例看起来像这样简单:

solo.sendkey(solo.menu);solo.clickontext("more"); // searches for the first occurence of "more" and clicks on itsolo.clickontext("preferences");solo.clickontext("edit file extensions");assert.asserttrue(solo.searchtext("rtf"));

如果你全职开发android app,那么买一个genymotion emulatorlicense吧。 genymotion 模拟器运行更快的秒帧的速度,比起典型的avd模拟器。他有演示你app的工具,高质量的模拟网络连接,gps位置,等等。它同时还有理想的连接测试。 你若涉及适配使用很多不同的设备,买一个genymotion ag凯发k8国际的版权是比你买很多真设备便宜多的。

注意:genymotion模拟器没有装载所有的google服务,如google play store和maps。你也可能需 要测试samsung指定的api,若这样的话你还是需要购买一个真实的samsung设备。

proguard 是一个在android项目中广泛使用的压缩和混淆打包的源码的工具。

你是否使用proguard取决你项目的配置,当你构建一个release版本的apk时,通常你应该配置gradle文件。

buildtypes { debug { minifyenabled false } release { signingconfig signingconfigs.release minifyenabled true proguardfiles 'proguard-rules.pro' }}

为了决定哪些代码应该被保留,哪些代码应该被混淆,你不得不指定一个或多个实体类在你的代码中。 这些实体应该是指定的类包含main方法,applets,midlets,activities,等等。 android framework 使用一个默认的配置文件,可以在sdk_home/tools/proguard/proguard-android.txt 目录下找到。自定义的工程指定的 project-specific 混淆规则,如在my-project/app/proguard-rules.pro中定义, 会被添加到默认的配置中。

关于 proguard 一个普遍的问题,是看应用程序是否崩溃并报classnotfoundexception 或者 nosuchfieldexception 或类似的异常, 即使编译是没有警告并运行成功。 这意味着以下两种可能:

proguard 已经移除了类,枚举,方法,成员变量或注解,考虑是否是必要的。

proguard 混淆了类,枚举,成员变量的名称,但是这些名字又被拿原始名称使用了,比如通过java的反射。

检查app/build/outputs/proguard/release/usage.txt文件看有问题的对象是否被移除了。 检查app/build/outputs/proguard/release/mapping.txt 文件看有问题的对象是否被混淆了。

in order to prevent proguard from stripping away needed classes or class members, add a keep options to your proguard config: 以防 proguard 剥离 需要的类和类成员,添加一个 keep选项在你的 proguard 配置文件中:

-keep class com.futurice.project.myclass { *; }

防止 proguard 混淆 一些类和成员,添加 keepnames:

-keepnames class com.futurice.project.myclass { *; }

查看this template's proguard config 中的一些例子。 更多例子请参考proguard。

在构建项目之初,发布一个版本 来检查proguard规则是否正确的保持了重要的部分。 同时无论何时你添加了新的类库,做一个发布版本,同时apk在设备上跑起来测试一下。 不要等到你的app要发布 "1.0"版本了才做版本发布,那时候你可能会碰到好多意想不到的异常,需要一些时间去修复他们。

tips每次发布新版本都要写 mapping.txt。每发布一个版本,如果用户遇到一个bug,同时提交了一个混淆过的堆栈跟踪。 通过保留mapping.txt文件,来确定你可以调试的问题。

dexguard 若果你需要核心工具来优化,和专门混淆的发布代码,考虑使用dexguard, 一个商业软件,proguard 也是有他们团队开发的。 它会很容易将dex文件分割,来解决65k个方法限制问题。

文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

ag凯发k8国际的版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2023年3月24日 上午8:27
下一篇 2023年3月24日 上午8:37

相关推荐

  • 你是否感觉近几年工程利润越来越少了?有些项目干完不赚反亏,奇怪的是同行却始终在赚钱? 导致项目亏损的原因有很多,行业大环境、市场竞争、突发事件等等,有些客观原因,通过人为是无法改变…

    科研百科 2023年9月1日
    116
  • 艾溪湖管理处吾悦社区开展“减塑捡塑环境日 吾悦-u0026#39;小哥-u0026#39;齐上阵”宣传活动

    2023年6月5日是第52个世界环境日,主题为“减塑捡塑”,为进一步优化辖区环境,打造干净、整洁、优美的居住环境,近日,艾溪湖管理处吾悦社区带领“悦”小哥驿站的快递小哥一起加入此次…

    科研百科 2023年6月29日
    114
  • 在这个数字时代,软件成为了我们日常生活和工作中不可或缺的工具。无论是提升生产力、创意表达还是解决问题,软件都为我们提供了无限的可能性。然而,许多人对软件的基本功能感到困惑,不知道如…

    科研百科 2024年4月30日
    44
  • 公司新版宣传片#宣传片(公司新版宣传片展示出了)

    郑蝶机格林公司是铸锻件精品智造者。公司从传统制造转向智能制造,从工人到工匠,以无限的创造力赋予产品新生,以专注的态度铸就精益品质,以全新的发展理念助力民族工业腾飞。郑州煤机格林材料…

    科研百科 2024年2月5日
    57
  • 张国栋(栋梁)造价设计:如何根据制定新的工时定额?(张国栋工程造价)

    针对当前工时定额研究方法中所存在的局限性,同时结合现代制造环境的特点,提出了基于产品制造难度系数的工时定额制定新方法。 1 新方法的施行流程主要分以下四个阶段来进行: 第一阶段:产…

    2022年9月7日
    229
  • 8月16日晚,在福田区委和福田街道党工委的领导下,cbd商圈党委召集辖区60家企业党支部书记和委员,近70人在cbd商圈党群服务中心召开“不忘初心,牢记使命”主题教育活动暨cbd党…

    科研百科 2023年6月5日
    237
  • 同济大学协同办公系统 同济大学是一所拥有悠久历史和优秀文化底蕴的名校,其教育教学和科学研究领域一直处于国内领先地位。然而,随着学校规模的不断扩大和业务的不断拓展,传统的协同办公方式…

    科研百科 2024年6月4日
    30
  • 智慧党建 数字党建 vr党建综合完整ag凯发k8国际的解决方案(智慧党建vr建设方案)

    党建文化教育在党风和党执政能力建设、保持和发展党的先进性方面具有着重要作用。随着当代信息技术的不断发展,多元化立体式的信息传播,多方位的影响人思想和意识形态。党建文化教育要抢占意识…

    科研百科 2023年2月9日
    744
  •   据中国乡村之声《三农中国》报道,近日,大家开始对2016年中央一号文件的期待正逐渐升温。中国乡村之声特约评论员、《经济参考报》记者林远分析,新的一号文件将有望继续聚焦现代农业。…

    科研百科 2022年5月30日
    262
  • 【第一百三十三期】潍坊市应急管理局·《政策访谈》

    潍坊广电新媒体讯4月25日上午9:00–10:00,潍坊市应急管理局党委书记王法顺走进潍坊市广播电视台新闻广播《政策访谈》直播间,解读了应急管理等政策,并就市民关心的问…

    科研百科 2023年10月2日
    121
网站地图