如何使用Web3j在Android Studio中读取智能合约方法返回的正确值?
解决Web3j读取智能合约view函数返回值的问题
嘿,我来帮你搞定这个问题——你现在踩的是Web3j调用只读合约函数的常见坑:把只读函数当成了需要发送交易的写操作来调用。
问题出在哪?
你写的这段代码:
Log.d(TAG, "counter Result: ${identityContract.name.sendAsync().get()}")
sendAsync()是用来发送会修改区块链状态的交易(比如合约里的setName这类写操作),调用它会返回TransactionReceipt交易凭证,完全不是你要的函数返回值。而你的getName()和getAge()是view类型的只读函数,根本不需要发起交易,直接本地调用就能拿到结果。
正确的写法来了
Web3j为每个view/pure类型的合约函数都生成了对应的callAsync()方法,这才是你该用的:
获取名字(getName())
// 调用callAsync()而不是sendAsync() val userName = identityContract.getName().callAsync().get() Log.d(TAG, "获取到的名字: $userName") // 这里会输出你构造函数里设置的 "Shoaib Khalid"
获取年龄(getAge())
val userAge = identityContract.getAge().callAsync().get() Log.d(TAG, "获取到的年龄: $userAge") // 输出 22
额外提醒(避免Android ANR)
注意get()方法会阻塞当前线程,在Android里直接用的话容易引发ANR,建议配合协程或者异步回调处理:
// 用协程在IO线程执行,避免阻塞主线程 lifecycleScope.launch { val name = withContext(Dispatchers.IO) { identityContract.getName().callAsync().get() } Log.d(TAG, "协程获取到的名字: $name") }
最后再强调下:callAsync()是本地执行,不耗Gas,也不会在链上留交易记录,专门用来读数据;sendAsync()才是给写操作准备的,会发起真实交易。
内容的提问来源于stack exchange,提问作者Shoaib Kakal
相关产品推荐
相关产品推荐

