2025-07-15 21:29:25
本文主要介绍一下 KMP/CMP 项目的组织结构和集成方式,从而概览整个技术架构,对其有个总体上的认知。
对于如何创建 KMP 项目可以直接使用官方的工具:
具体的调试步骤和环境可以看官方文档:https://www.jetbrains.com/help/kotlin-multiplatform-dev/quickstart.html
官方的项目结构文档:https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-discover-project.html
KMP/CMP 参考项目 Fread:https://github.com/0xZhangKe/Fread
首先 KMP 项目目前仍然使用 Gradle 构建,因此项目结构和我们的 Android 项目大体上类似,但是源码文件夹有所不同,毕竟是跨平台项目,肯定存在一些代码是各端独自实现的情况,那么肯定也需要不同的平台文件夹存放该平台特有的代码及实现。
所以一个 KMP 项目的模块结构如下:
目标平台有 Android 和 iOS,commonMain 则表示所有平台的共享代码。
上图中的 commonMain
中存放的就是通用代码,这里的代码可以被所有平台使用,也会参与所有平台的构建流程。
其中的代码与平台无关,也不可以使用任何平台独有的 Api,只能使用其它模块或者支持 KMP 的依赖库中的 common code。当然目前也是好起来了,越来越多的三方库都在已经支持了 KMP,大部分情况下都有现成的库直接用。
对于不同的编译目标平台,commonMain
中的代码也会编译成不同的产物,这一切都是 Kotlin 编译器的功劳。
目标平台定义了 common code 将会被编译到哪些平台。对于不同的平台编译的产物也不同,比如 androidTarget
产物是 aar,iOS 产物是 framework
。
另外 Target
本身只是一个标识符,用于标识不同的目标平台,编译器将会根据这些目标平台的不同来编译出不同的产物。包括依赖包管理也是通过 Target
标识的。
我们可以通过在 gradle 的 kotlin
块内管理 target:
kotlin {
jvm() // Declares a JVM target
iosArm64() // Declares a target that corresponds to 64-bit iPhones
}
通过声明 jvm
和 iosArm64
目标,commonMain
中的代码将被编译为这些目标:
Target 还提供了 Gradle DSL 用于一些配置,其中包括通用配置和平台独有的配置。
通用配置是指在任何 target 内都可以使用的配置。
name | Description |
---|---|
platformType |
目标平台类型,取值范围:jvm 、androidJvm 、js 、wasm 、native 、common
|
artifactsTaskName |
构建此目标的最终产物的任务名称 |
components |
用于设置 Gradle 发布内容的组件 |
compilerOptions |
用于该目标的编译器选项,此声明会覆盖在顶层配置的任何 compilerOptions {} 设置。 |
此外还有一些平台独有的配置。
kotlin {
wasmWasi {
nodejs()
binaries.executable()
}
js().browser {
webpackTask { /* ... */ }
}
linuxX64 {
binaries {
executable {
// Binary configuration.
}
}
}
androidTarget {
publishLibraryVariants("release")
}
}
具体配置可以看官方文档:https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-dsl-reference.html
Kotlin Source set 是一组具有各自 Target、依赖项和编译器选项的源文件。它是在 KMP 项目中共享代码的主要方式。
Source Set 的特性:
Kotlin 提供了一系列预定义的源集。其中之一是 commonMain
,它存在于所有 KMP 项目中,并编译为所有声明的目标。
在 Gradle 脚本中,我们可以通过 kotlin.sourceSets {}
块内的名称访问 Source set:
kotlin {
sourceSets {
commonMain {
// Configure the commonMain source set
}
}
}
这里的 commonMain 对应的就是我们上面第一张截图中的那个 commonMain 文件夹,一般来说每个常规的 source set 都会有一个自己的代码文件夹,不同模块中的相同的 source set 文件夹中的代码可以互相调用,因为他们最终都会被编译到同一个产物内。
因此 source set 主要是用来管理该 Target 下的代码集合的,比如为该 Target 添加某些依赖库,设置源码路径等。
跟 Target 类似的是,source set 也提供了针对平台特有的设置。
在设置依赖库的时候我们经常会用到这个功能,比如我们现在需要一个视频播放器,但是没有找到适合业务的跨平台播放器组件,以此需要各端独自实现,那么我们在 Android 端需要依赖 media3,iOS 端需要依赖另外一个视频播放器的组件,那么就可以通过 source set 设置不同的依赖。
kotlin {
sourceSets {
androidMain {
dependencies {
implementation(libs.media3)
}
}
iosMain {
dependencies {
implementation(libs.ios.video.player)
}
}
}
}
通过这样的方式,我们就可以针对不同的平台添加不同的依赖,这些依赖可以在各自的文件夹中依赖到,比如我们可以在 androidMain
文件夹中直接使用 media3
,在 iosMain
中使用 iosVideoPlayer
。
在编译阶段,编译器会针对当前编译的 Target 选择使用不同的 source set,比如编译到 Android 平台,那么会选择 commonMain
+androidMain
的代码和依赖库进行编译。
除了上述我们说到的普通 source set 之外,还有一种叫做中间源集。
中间源集的概念其实很简单,比如我们现在的 KMP 项目同时支持了 Android、 iOS 和 macOS,现在我们需要一个用于生成 UUID 的函数,这个函数各端各自实现。但实际上 iOS 和 macOS 的实现是一致的,我们总不能同样的代码在 iosMain
和 macosMain
中各写一份吧,这样很容易出错。
于是 KMP 提供了中间源集用于解决这个问题,在上述情况中,我们可以直接将代码写在 appleMain
中,appleMain
可以使用 Apple 平台的能力,并且在 iosMain
和 macosMain
中都可以依赖到其中的代码。
完整的层次结构如下,其中彩色的部分可以理解为 Intermediate source sets.
从上面的示例和截图中可以看出来,source set 源码文件夹都带了一个 Main/Test 后缀,Main 包含生产代码,Test 后缀就表示该 source set 的测试代码,他们之间会自动建立关联,Test 可以直接依赖到 Main 中的代码。
Kotlin 也提供了支持 KMP 的默认测试框架,其中包含@kotlin.Test
注解以及各种断言方法,例如assertEquals
和assertTrue
。
当然我们也可以像常规测试一样,为每个平台在其各自的 source set 中编写平台特定的测试。也可以为每个 source set 设置平台特定的依赖项,例如 JUnit
针对 JVM 和 XCTest
iOS 的依赖项。要针对特定目标运行测试,请使用<targetName>Test
任务。
dependsOn
是两个 source sets 之间的特定关系,通过 dependsOn
将整个 source sets 关系设置为一个树状结构,不过一般来说我们并不需要手动设置。
kotlin {
// Targets declaration
sourceSets {
// Example of configuring the dependsOn relation
iosArm64Main.dependsOn(commonMain)
}
}
在某些情况下,我们可能需要在项目中设置自定义中间源集。假设有一个项目会编译到 JVM、JS 和 Linux,并且只想在 JVM 和 JS 之间共享一些源。在这种情况下,我们应该为这对目标找到一个特定的源集。
Kotlin 不会自动创建这样的源集,但我们可以使用 by creating
手动创建它:
kotlin {
jvm()
js()
linuxX64()
sourceSets {
// Create a source set named "jvmAndJs"
val jvmAndJsMain by creating {
// …
}
}
}
但此时我们自己创建的 jvmAndJsMain
的依赖关系是独立的,因为我们并未手动指定任何依赖关系,此时就需要使用上面说的 dependsOn
了。
kotlin {
jvm()
js()
linuxX64()
sourceSets {
val jvmAndJsMain by creating {
// Don't forget to add dependsOn to commonMain
dependsOn(commonMain.get())
}
jvmMain {
dependsOn(jvmAndJsMain)
}
jsMain {
dependsOn(jvmAndJsMain)
}
}
}
现在,该项目的依赖关系如下:
首先,我们可以通过如下方式给不同的 source set 添加不同的依赖库:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
jvmMain.dependencies {
implementation("com.google.guava:guava:32.1.2-jre")
}
}
}
被添加到 commonMain
中的依赖库会被传递到所有 Target 中,而添加到 jvmMain
中的依赖库只会在 jvmMain
文件夹中可见。
Kotlin 会把每个依赖关系解析为一组 source sets,而这组 source sets 中的每一个都必须和当前使用它的源集(consumer source set)在目标平台上兼容。
也就是说你添加的依赖库的 target 列表必须包含你的项目的 target 列表,缺少一个都会被视为不兼容。
举例来说,如果你当前的项目 target 中包含了 jsMain,但是你打算添加的依赖库的 target 中未包含 jsMain,那么就会被视为不兼容,那么就无法使用这个库。
Kotlin Multiplatform 的 common 源集(commonMain
)会被编译多次(为不同 Target),因此依赖库版本必须一致。
为什么要对齐版本(align versions)?
commonMain
会参与多个目标(如 Android、iOS 等)的构建。commonMain
使用的依赖版本不一致,会导致编译出来的 .klib 不一致,从而出问题。commonMain
的地方依赖的库版本相同。举个例子:
首先 commonMain
中声明了如下依赖:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
同时 androidMain
中又声明了如下依赖:
implementation("androidx.navigation:navigation-compose:2.7.7")
但是这个 navigation
库内部依赖了 coroutines 1.8.0
。
那么问题来了:
androidMain
和 commonMain
是要一起编译的commonMain
也会用 1.8.0 的 coroutines
commonMain
的代码iosMain
等所有平台
Kotlin Multiplatform 项目中,只要有任何 source set 引入了较高版本的共享依赖,Gradle 就会自动将这个版本同步到所有需要它的 source set 上,以确保生成的 common 代码在所有平台上都是一致的。
对于 iOS 平台来说,KMP 项目的代码会直接编译成 framework 产物给到 iOS 项目集成继续参与 Xcode 的编译流程。那么具体来说是如何集成的呢?比如我们直接 clone 一个 KMP/CMP 项目到本地然后直接用 Xcode 打开可以直接运行,那么 Kotlin 代码如何开始编译?
Xcode 构建阶段(Build Phase)可以添加一些自定义脚本,对于一个默认支持了 KMP 的 Xcode 项目来说,构建阶段会被添加一行自定义脚本,该脚本用于执行一个 gradle 命令以此生成 Xcode 需要的 framework 文件。
我们可以打开 Xcode 项目视图中的 Build Phase 看到这个脚本:
其实我们也可以自己运行这个脚本,运行完成后会看到 build 文件夹下生成了 framework 文件。
好了现在 frameworks 已经生成了,剩下的就是如何把这这个文件添加到 Xcode 项目的依赖中去。
我们接着打开 Xcode 的项目视图中的 Build Settings 往下找到 Search Paths 栏,可以看到 gradle build 目录中的 frameworks 路径已经被添加到项目中了。
这样整个 Xcode 的构建环节就搞明白了,首先通过自定义编译脚本调用 gradle 编译出 framework 文件,并且预先将该路径添加到了 Xcode 构建依赖中,然后 Xcode 内就可以把 KMP 模块当作一个普通的 framework 依赖库使用了。
当然这些配置也可以根据自己的项目需要修改,具体的配置也可以在 project.pbxproj 文件内看到。
首选还是直接看官方文档:https://developer.android.com/kotlin/multiplatform/migrate
因为 Kotlin for iOS 代码最终会编译成 framework,所以如果现有的 Xcode 项目如果想集成 KMP 其实也可以不必设置编译脚本,也不必对现有项目做其他的更改,只需要像依赖普通的库一样依赖这个 Kotlin 的产物即可。
The post 一个KMP/CMP项目的组织结构和集成方式 first appeared on 张可的博客.
2025-04-27 13:08:14
大家好,Fread 项目开发到今天已经有两年半了,上线也已经八个月了,目前项目趋于稳定,现在决定使用 Apache 2.0 协议将其开源。
https://github.com/0xZhangKe/Fread
首先介绍下 Fread 的技术栈。
Fread 是一个使用 KMP(Kotlin Multiplatform) 和 CMP(Compose Multiplatform) 的移动客户端应用,所以编程语言使用的是 Kotlin,技术栈也都是基于 Kotlin 的,主要如下。
上面列举了一些具有代表性的依赖库,除此之外还有很多其他的库没有列举出来,从这些具有代表性的库可以大概了解到 Fread 的技术栈。
Fread 是一个去中心化的联邦宇宙 Micro blogging 社交客户端,目前已经支持了 Mastodon、Bluesky、RSS 三种社交平台协议,这意味着你可以在同一个 App 中同时使用这三种社交平台,Fread 不仅提供了 Micro blogging 社交的一致性,也保持了不同平台的特色功能。 更重要的是,Fread 支持创建一个同时包含了三种来自不同平台的 Feeds 流,这打破了协议之间的壁垒,进一步增强了去中心化的能力,另外 Fread 也专注于提供漂亮舒适的 UI/UX。
Fread 之所以现在决定开源,一方面是刚开始没考虑好到底是付费下载还是免费试用,但是上线一周后就直接改成了免费下载,但是之前因为是闭源所以仓库中有一些敏感的数据信息,担心开源后会泄漏出去,现在已经解决了这个问题。另外我对 Fread 有不少设想和规划,开源后需要面临其他人提交 PR 的情况,这可能会打乱开发节奏,所以在最近支持了 Bluesky 之后,项目也稳定下来,才开始着手开源的事情。
目前 Fread 虽然使用了 KMP 跨平台,iOS 也能运行起来,但是只上架了 Android 版,iOS 还有一些适配工作没完成,未来适配完成后会上架 App Store。
之前为了监控线上 Crash 情况和用户量所以接入了 Firebase analytics,后来又因为消息推送接入了 FCM,并且为了中转 FCM 消息我自己搭建了一台中继云服务,这里面因为涉及到我自己的 Firebase 账户和云服务信息,所以这部分的内容从 Fread 仓库中移除了,这个在我的私有仓库,可以作为 Fread 子模块进行编译,并且设置了可选编译,意思是指通过 Fread 主仓也可以编译,功能没有什么变化,只是会缺少 Firebase 的能力,其他没有任何影响,但是我这里可以编译出带有 Firbase 能力的包并且上架 Google Play,未来在 F-droid 上架的版本也会是不包含 Firebase 的版本。
关于 Fread 更多的技术细节大家可以直接查看代码,未来我可能会继续发布一些博客介绍 Fread 中的一些设计和细节。
https://play.google.com/store/apps/details?id=com.zhangke.fread
The post 历时两年半开发,Fread 项目现在决定开源 first appeared on 张可的博客.
2025-04-22 22:25:46
Fread 初版上线之后的大部分时间除了使用 Kotlin Multiplatform 兼容 iOS 版本之外,剩下的绝大部分时间都是在支持 Bluesky 社交平台,这个工作从今年年初开始持续到最近终于完成,现在下载最新版本的 Fread 即可体验。
Fread 是一个去中心化的 Micro blogging 社交客户端,目前已经支持了 Mastodon、Bluesky、RSS 三种社交平台,这意味着你可以在同一个 App 中同时使用这三种社交平台,Fread 不仅提供了 Micro blogging 社交的一致性,也保持了不同平台的特色功能。
更重要的是,Fread 支持创建一个同时包含了三种来自不同平台的 Feeds 流,这打破了协议之间的壁垒,进一步增强了去中心化的能力。另外 Fread 也专注于提供漂亮舒适的 UI/UX,因为 Fread 碰巧有一位专业的设计师。
使用上也非常简单,在添加内容页面可以看到第一个就是 Bluesky,点进去登录即可。
登录完成后进入首页大概长这个样子,这里的 TAB 和在网页端的一致。
Fread 还提供了一个 Bluesky 不太好用的功能,就是拖动 TAB 排序(Bluesky 的排序功能一直报错),在首页左侧的抽屉中点击编辑 Bluesky 按钮,进入编辑 TAB 页面,这里不仅可以新增/删除 Feeds,还可以拖动排序。
Bluesky 特有的引用帖子的功能在新版本中也得到了支持,帖子样式新增了引用类型,另外在帖子下面的操作按钮行中也新增了一个引用按钮,点击后进入发帖页面会有引用帖子的展示。
本次改版还包括对发帖页面的重构,对于回复内容,现在页面会提供被回复内容的展示,如下图所示。
不仅仅是 Bluesky 的发帖页面,Mastodon 的发帖页面同样也包含了这些改动。未来还会继续支持同时将一个帖子发布至多个账号。
此外一些其他的主要功能 Fread 也已经支持,比如通知中心,个人信息修改等等。不过私信功能目前还未支持,这个做起来比较麻烦,会在发帖功能重构完成后开始。
以上就是 Fread 最新版本的主要改动,欢迎大家下载体验,完全免费,近期有计划将 Freed 开源出来,届时也欢迎大家提 bug 和 PR。
大家也可以关注我的长毛象和 Fread 官方账号,同步发布关于 Fread 最新的动态。
https://play.google.com/store/apps/details?id=com.zhangke.fread
The post Fread 最新版本已支持 Bluesky first appeared on 张可的博客.
2025-03-16 20:26:15
距离上一次写电影记录已经好久了,最近又看了好几部影视剧,然后打算把看的书也记录一下,但是好多剧情都忘了,没办法写的很详细,以后打算看完一部就在豆瓣写个短评。
(WordPress 好像还不支持 NeoDB /豆瓣链接的 embed?一个个截图好麻烦)
哲学的历程还在看(已经看了好久了好没看完),最近看了大卫休谟到康德。
康德在整个哲学史中都有非常重要的意义,他把人类从休谟的怀疑论中解救出来,不过他的理论也很难懂,我还没看完,感觉哲学史从黑暗中世界开始开始到康德这里才越来越有意思起来。
一本书速通中国政治体制和主要事物。系统的了解了一下政府结构和行事方式,已经看到了中国改开之后经济发展的大致脉络,挺好的一本书,内容不多,很快就能读完,推荐。
这本书是关于养娃的,有娃之前我老婆就让我看这本书,主要是孩子大脑的特性和家长的教育方式,也会涉及部分孩子大脑的原理,了解了原理就更容易养娃,建议所有家长都去看,很棒的一本书。
还没看完,关于贝叶斯主义的介绍,贝叶斯主义不仅是一种概率计算方式,也是一种思考方式,甚至是看待客观世界的方式,相比较于传统概率论,贝叶斯主义更注重概率随着条件变化而变化,并且会给出概率分布,并且贝叶斯主义会纳入主观偏见调整计算参数,从而得到更准确结论。对我来说,这个想法确实会影响我的思考方式,降低心里负担。
又一部安哲的电影,我太喜欢他的电影中的调调了,他的空镜头和长镜头可以说非常厉害。
雾中风景,绝望、冷漠、孤寂的一部电影,姐弟俩位了寻找一个不存在的父亲踏上了旅程,安哲用很多镜头和片段隐喻电影的主题,未知的旅程就是迷雾,沿途的风景就是他们的经历,这不是喜剧,也不能算是悲剧,这就是人生。弟弟亚历山大似乎有某种宗教隐喻,当然我没看明白。
贾樟柯的新电影,主演仍然是他老婆赵涛,贾樟柯是真的很喜欢拍基层文艺从业者了,全电影通过赵涛视角来了个华语金曲大串烧。我挺喜欢这种平凡视角下的审美,我觉得美是存在于任何一个角落。这个电影故事线很长,社会变迁差不多也是我从童年到现在,所以很有代入感。
终于等来了第二季,没想到还是原来的剧情,而且嘎然而止,没看爽,没了第一季那种新鲜感这部剧也就平平无奇了,孔刘公园踩面包真的很帅。
一个俄罗斯电影,故事发生在俄罗斯北部,这是我最喜欢的地方之一,大片寒冷的平原,冷冽的寒风和刺骨但是干净的海水,这都是我最爱的东西,所以这部电影光看风景就够了。剧情原本以为挺温馨的,结果并不是,有很强的政治隐喻意味,不过不考虑隐喻单纯的剧情也很有意思了。
闲着没事看的喜剧片,没想到这竟然还是个系列电影,不过我只看了第一部,当初上映时热度挺高的,我看了感觉一般,笑点也还行,纯纯的商业片。
姜文和葛优,光看这俩演员就不错了,挺好的电影竟然一直没看。影片是关于秦始皇和高渐离的故事,也是权利和艺术的故事,至少从秦朝开始,文化就是权利的附庸者,对待文人,权利有一百种方式让其臣服,即使今天也是这样。
中年男人的身份认同危机,从好莱坞到百老汇,努力摆脱商业片印象,开始追求艺术,最后甚至付出自己的一切。
超现实主义、荒诞、长镜头、话剧与电影,难怪评分这么高。
Movie – Birdman or (The Unexpected Virtue of Ignorance)
这是一部通过电影从业者们的故事开始的电影艺术史,既有从小人物到好莱坞风云人物的故事,也有从黑白电影到如今 IMAX 3D 电影的故事,好莱坞恢弘的史诗导演完全给拍出来了。不过最后那段混剪虽然剪的很好但有种在看 B 站的感觉。
作为一个占尽性别红利的男人确实不太敢对这部电影有什么评价,但是拍的真不错,喜欢。导演或者编剧真的很懂老中了,很多微妙的小想法小细节都给拍的清清楚楚。
没看过原著和其他版本,开头真的很吓人,但故事还是很温暖的,韩剧太强了。
本来以为会很像迷雾类型的,结果也确实有一点像,不过远没有迷雾那种克苏鲁的恐怖感,也是闲着没事看的,也还可以,没有很大的场面,整个剧情都发生在半座桥上。
太炸裂了,看之前完全没想到会这么炸裂。看了介绍和名字以为是科幻片,看了开头以为是鸟人类型的片,看完发现是惊悚+讽刺男权片。
娱乐圈真的是人吃人(物理上),女演员不得不迎合男性审美,这一切都太过恶心。
太长了导致我现在才看,而且系列电影我更偏向于只看第一部,帕西诺确实很帅,年轻和老了都很帅。
双线叙事,一个是从零创业的年轻人,一个是开拓新市场的年轻人,不同的时代,不同的境况,放在一起还是挺有意思的,比第一部好看点。
Movie – The Godfather: Part II
大年初一就去看了,第一部我是真喜欢,第二部其实也还可以,每个电影都有缺点,第二部的缺点我倒是觉得也还好,无伤大雅,不至于这么低的分数,我应该可以给到 7.5 分,只是女性奉献自己成全男性这样的桥段还是很下头,剧情也比较单调,其实邓婵玉的性格已经塑造的非常血性了,只不过恋爱桥段和最后奉献自己让电影大打折扣,不过还是比哪吒2好多了。
Movie – Creation of The Gods Ⅱ: Demon Forces Demon
作为一个电影院爱好者,院线电影好一点的基本都去看,除非没空。
哪吒 2 票房高的离谱,我最多打 7 分。笑点真的很尬,人物建模真的很丑,屎尿屁笑点真的低俗,剧情也真的简单。打斗场面说来就来,为了燃而燃,所以后面看麻了已经没啥感觉了,总之结尾燃一下就可以高分。
易烊千玺真的很想摆脱路人对他的印象了,这个电影一点也不端着,这一点比别的流量明星好多了。
我挺喜欢这种拍小人物、小故事、少数群体的电影,他们需要被公众看到,他们的需求应该被满足。
电影本身拍的也挺好的,只是为了凸显外婆的特质显得有点跳脱和刻意,脑瘫患儿的恋爱线感觉也很棒,情感需求和性需求都是人类的基本需求,没什么不好意思说的,不必谈性色变。
又一部黑帮电影,之前一直以为看过了呢,结果没看。我挺喜欢这种从小人物视角开始的黑帮电影,剧情更容易理解,人物塑造也能随着剧情推进逐渐丰满。
第二部终于出来了,这次是哪都通的几个顶尖异人联手去碧游村打怪。特效感觉很可以了,以前国产剧特效太过离谱,这个至少看起来很和谐,不奇怪,国产特效要是都能做到这个水准就行了。只是里面没有太大的场面,特效没有那么多的视觉冲击力。
The post 书影音记录:Dec 13, 2024-Mar 15,2025 first appeared on 张可的博客.
2025-03-05 20:40:01
前段时间看了置身事内这本书,今天就来盘一下税改和土地财政这个与我们息息相关的话题。
我国在 1994 年进行了一次税制改革,这次税改都中国的未来产生了非常深远的影响,也直接影响到了我们今天的日常生活,下面就来简单介绍一下这两者的成因和联系。
在说税改之前先介绍一下当时的现状,上世纪八十年代,我国税收制度主要是分级包干模式。具体表现如下:
此外,1994 年正值改革开放初期,1992 年邓小平南方讲话后,改革开放进入新阶段,此时正需要建立全国统一市场,打破地方壁垒,中央统筹能力也需要财政的支持。
基于上面的原因,我国在 1994 年进行了分税制改革,核心是明确中央与地方财政收入分配与事权划分,建立现代财政体制。
本次税改主要包括三个方向。
税收机构分设国税、地税两套机构,与地方财政部门脱钩,省以下税务机关以垂直管理为主,由上级税务机构负责管理人员和工资。
建立转移支付制度,中央通过转移支付平衡地区间的差异。
1994 年的税改是 90 年代最成功改革,改革扭转了“两个比重”不断下滑的趋势:中央占全国预算收入的比重从改革前的 22% 一跃变成 55%,并长期稳定在这一水平;国家预算收入占 GDP 的比重也从改革前的 11% 逐渐增加到了 20% 以上。
以上就是 1994 年税改的主要内容,我们今天可能会觉得中央总是有能力协调一切事情,不管是财政还是权利都远高于地方,但这其实很大程度上都是因为这次税改,几乎所有的问题都可以靠钱解决,这次改革让财政大权重新回到中央,这也为了中国未来的一系列改革垫定了基础。
当然,除此之外还有一些缺点,比如地方的财务和事权不匹配,地方政府没钱了就只能探索其他收入,那么最终探索出来最行之有效,最赚钱的方式就是土地财政。
经过分税制度改革,地方财政上交国家,但事情并没有减少,做事情都是需要花钱的,因此地方政府财政压力增大。另外中央要求地方政府加强对公共设施建设也进一步增加了地方的财政负担。
先说下我国土地政策,我国实行土地公有制,城市土地归国家所有,农村土地归集体所有。农地要转为建设用地,必须先经过征地变成国有土地,然后才可以用于发展工商业或建造住宅。
当然,税改之后并不是立马开始发展土地财政的,地方政府想要靠着土地赚钱还需要一些政策上的支持才行,这拐点就发生在 1998 年。
首先是单位停止福利分房,逐步实行住房分配货币化,大量资金涌入楼市,住房需求增加,房价逐渐开始攀升。
其次是修订后的《中华人民共和国土地管理法》开始实施,规定了农地要想转为建设用地,必须经过征地后变成国有土地,这也就确立了城市政府对土地建设的垄断权力。
在我国,房价跟地价是挂钩的,根据市场经济理论,商品价格由供需关系决定,稀有商品价格更高。由于上面说的土地政策原因,商用土地面积由政府控制,而非商用面积则不允许建造住宅。那么只要简单的控制土地面积从而就可以控制房价。当然,地方政府还需要考虑耕地红线的限制。
2002 年,国土部明确四类经营用地(商业、旅游、娱乐、房地产)采用“招拍挂”制度,即招标、拍卖、挂牌。这个制度推动土地市场化,提高了土地出让的收益。
在多轮政策的影响下,土地出让收入一路飙升。2003 年就已经达到了地方公共预算收入的 55%,2010 年达到地方公共预算收入的 68%。最近两年这一比重虽有所下降,但土地转让收入的绝对数额还在上涨,2018 年达到 62910 亿元,比 2010年高 2.3 倍。
除了土地出让收入之外,土地财政还包括土地使用和开发有关的各种税收。主要包括土地增值税和房地产开发以及建筑企业的企业所得税。
时至今日,土地财政已是强弩之末,经济增长只能依靠健康的产业结构和政策,希望我们普通人都能在这场浪潮中安全着陆吧。
The post 中国的分税制改革与土地财政 first appeared on 张可的博客.
2025-03-02 14:21:11
前段时间高中同学结婚,因为是周六,我也赶了回去,高铁单程三小时,早上出发晚上还能再回到家,中间在同学家里和一众老同学一起待了半天。
由于同学是隔壁市的,习俗和我们有所不同,所以虽然我们上午十点多就到了,但一直到下午三点才吃上饭,中间的时间因为婚礼现场吵闹,我们趁着蓝天白云选择去附近的乡下走一走聊聊天。
我们这个圈子的人差不多都来了,六七个人左右,毕竟是高中同学,毕业后大家各奔东西,现在距离高中毕业已经十多年,大家也都是三十岁的人了,再聚在一起其实很多方面都已经大不相同了。
我不知道从什么时候养成了一个习惯,在跟别人交流的时候,尤其是陌生人,我会下意识的思考对方说话所包含的潜在逻辑和原因,我还会去思考对方这么说的原因的一些可能性。
比如上周我去买了个二手婴儿车,卖家是一个宝妈,看着年龄比我大一点,我去她家取货的时候我一边看婴儿车一边闲聊,然后她说这种东西买二手的最好,新的会有甲醛,我也跟着附和她。但另一方面她自己买的是新的,所以这就有一个矛盾,我下意识的想到了这一点,然后接着思考他为什么这么说,那可能是为了给我面子,或者保证我的尊严,毕竟买二手的东西的原因之一就是穷。
这样的行为其实已经成为我的潜意识了,很多时候自己都没有意识到这一点,好处当然就是可以快速的想到对方的言外之意,从而避免一些误会和尴尬,如果是从事于人打交道的行业那么这一点也更重要,不过还好我只需要跟计算机打交道。当然我自己仍然是一个直来直去的人,我喜欢这样的交流方式,效率高,大部分情况下隐瞒自己的真实意图也没什么用,聪明的人能看出来,并且真实的意图也不是什么见不得人的东西。
这样的缺点也是有的,很难跟别人发展更进一步的关系,也懒得跟大部分陌生人沟通。
说回这次跟朋友的聚会,文章标题说的主动降频其实就是主动取消这种下意识行为,用十年前的自己和大家相处。
如果有一个融洽的氛围,那么社交对我来说是正向的,我会觉得开心或者幸福。不同的氛围带来的感觉多少也会有点不同,日常生活中的这种融洽的社交氛围几乎只有家人。
另外我觉得人是复杂的,当我们选择说出一句话时这句话是我们无数多的经验和我们的内心综合最终的输出,我可以按照我的理解用一个原因来概括对方的动机,但我永远也无法理解对方的内心,或许他还有别的意思呢,既然无法理解,那最简单的方式就是单纯的理解语言的表面意思。
用最简单的方式与人相处更容易得到最简单的快乐和收获,那些看似有条理的分析只不过是我自己的臆想罢了。
所以这次回家还是挺开心的,十多年过去了,大家竟然都没怎么变,还可以像以前那样玩,只可惜平时工作不在一个城市,大家聚少离多,这样的机会越来越少了可能。
The post 社交关系中的“主动降频” first appeared on 张可的博客.