Android REST API 调用,后端没有响应新记录
Posted
技术标签:
【中文标题】Android REST API 调用,后端没有响应新记录【英文标题】:Android REST API call with no response from back end for new records 【发布时间】:2020-03-23 14:08:35 【问题描述】:我正在为课程项目开发android app
。我的应用程序有后端 (REST API
),我在 Heroku
上开发和部署了它。现在我正在尝试从后端获取数据。我使用了Retrofit
(network API
)和Moshi
(用于解析JSON
字符串)。
我第一次成功地从后端获得了3条记录的响应(这些记录是我在Ruby on Rails
中写API
时创建的)。然后为了测试应用程序,我从Postman
发送了POST
2 条记录,然后我再次运行应用程序。这一次我没有得到任何回应。然后我发送DELETE
操作最后 2 条添加的记录,我再次运行应用程序,这次我得到了旧记录的响应。然后我从Postman
发送另一个DELETE
操作以获取旧记录之一并发送POST
操作。然后应用程序没有显示任何响应。我删除了新记录,然后应用显示旧记录。
通常app
仅显示旧记录。每当我发送新的POST
操作时,我都没有得到回复。我对正在发生的事情感到惊讶。有人可以告诉我可能是什么问题吗?我已经清除了手机中的所有caches
,重启手机,重新安装了应用程序,但问题仍然存在。
(我可以从邮递员和浏览器成功获取所有数据)
EventApiService.kt
// 我定义 Retrofit 和 Moshi 对象的地方
private val BASE_URL = "https://eventnotifierjson2.herokuapp.com/"
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.baseUrl(BASE_URL)
.build()
interface EventApiInterface
@GET("events")
fun getEvents():
Deferred<List<Event>>
object EventApi
val retrofitService : EventApiInterface by lazy
retrofit.create(EventApiInterface::class.java)
=============================EventsListFragment 的视图模型
class EventListViewModel: ViewModel()
private val _eventResponses = MutableLiveData<List<Event>>()
val eventResponses : LiveData<List<Event>>
get() = _eventResponses
private val _responseStatus = MutableLiveData<String>()
val responseStatus : LiveData<String>
get() = _responseStatus
private val eventCoroutineJob = Job()
private val eventCoroutineScope = CoroutineScope(eventCoroutineJob + Dispatchers.Main)
init
retrieveEventsInBackground()
private fun retrieveEventsInBackground()
eventCoroutineScope.launch
// Get the Deferred object for our Retrofit request
var getPropertiesDeferred = EventApi.retrofitService.getEvents()
try
// this will run on a thread managed by Retrofit
val listResult = getPropertiesDeferred.await()
_eventResponses.value = listResult
Log.i("RETROFIT ZEK: ", _eventResponses.value.toString())
catch (e: Exception)
_responseStatus.value = e.message
override fun onCleared()
super.onCleared()
eventCoroutineJob.cancel()
=================================
class EventListFragment : Fragment()
lateinit var binding : FragmentEventListBinding
private val viewModel: EventListViewModel by lazy
ViewModelProviders.of(this).get(EventListViewModel::class.java)
private lateinit var eventAdapter : EventsRecyclerAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View?
binding = FragmentEventListBinding.inflate(inflater)
binding.setLifecycleOwner(this)
binding.viewModel = viewModel
initializeRecyclerView()
return binding.root
private fun initializeRecyclerView()
binding.eventsRecyclerView.apply
layoutManager = LinearLayoutManager(this@EventListFragment.context)
val cardDecoration = CardViewDecoration(30)
addItemDecoration(cardDecoration)
eventAdapter = EventsRecyclerAdapter()
adapter = eventAdapter
用于显示回收站视图和图像的 BindingAdapters
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Event>?)
val adapter = recyclerView.adapter as EventsRecyclerAdapter
adapter.submitList(data)
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?)
imgUrl?.let
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
Glide.with(imgView.context)
.load(imgUri)
.apply(RequestOptions()
.placeholder(R.drawable.ic_gerald_g_boy_face_cartoon)
.error(R.drawable.ic_gerald_g_boy_face_cartoon))
.into(imgView)
==========================从 JSON 数组中检索到的事件对象的数据类
data class Event(val id: Int,
val title: String,
val description: String,
val country: String,
val city: String,
@Json(name = "event_location") val eventLocation : String,
@Json(name = "event_date") val eventDate : String,
@Json(name = "event_time") val eventTime: String,
@Json(name = "event_status") val eventStatus: String,
@Json(name = "user_id") val userId: Int,
@Json(name = "created_at") val createdAt: String,
@Json(name = "updated_at") val updatedAt: String,
val eventimage : EventImage)
data class EventImage(
val url: String
)
fragment_event_list.xml // 我将 ViewHolder 膨胀到的视图
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.mobapproject.eventsroom.modelviews.EventListViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_
tools:context=".fragments.EventListFragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_
android:layout_
app:listData="@viewModel.eventResponses"
android:id="@+id/eventsRecyclerView"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
============================events_list_layout.xml // ViewHolder 的布局
<androidx.cardview.widget.CardView
android:layout_
android:layout_
app:cardElevation="10dp"
app:cardCornerRadius="2dp"
app:cardPreventCornerOverlap="false">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_>
<ImageView
android:layout_
android:layout_
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:imageUrl="@eventsData.eventimage.url"
android:id="@+id/event_image"
android:padding="0dp"
android:layout_margin="0dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_
android:layout_
app:layout_constraintTop_toBottomOf="@id/event_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical"
android:padding="10dp"
android:id="@+id/container1">
<TextView
android:layout_
android:layout_
android:id="@+id/event_title"
android:text="@eventsData.title"
android:textColor="#000"
android:textSize="19sp"/>
<TextView
android:layout_
android:layout_
android:id="@+id/event_location"
android:text="@eventsData.eventLocation"
android:textSize="15sp"
android:layout_marginTop="10dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</layout>
============================== JSON 响应如下所示
"id": 1,
"title": "Dummy title",
"description": "Dummy Description",
"country": "Italy",
"city": "Rome",
"event_location": "Rome",
"event_date": "2019-11-26",
"event_time": "2000-01-01T21:28:16.000Z",
"event_status": "open",
"user_id": 1,
"created_at": "2019-11-25T01:51:36.075Z",
"updated_at": "2019-11-25T01:51:36.075Z",
"eventimage":
"url": "http://res.cloudinary.com/zakstorage/....."
【问题讨论】:
向我们展示代码或错误日志,以便我们找出问题所在。 @Jayanth 没有错误,因为应用程序运行但空白片段。我已经编辑了这篇文章并添加了我到目前为止编写的代码。请检查一下好吗? 【参考方案1】:我遇到了问题,我犯了一个错误。我一直在向 POST 操作发送不正确的参数,而 Moshi 无法解析 NULL 值
【讨论】:
以上是关于Android REST API 调用,后端没有响应新记录的主要内容,如果未能解决你的问题,请参考以下文章
Android 我应该使用 AsyncTask 还是 IntentService 进行 REST API 调用? [复制]
通过更改android中的参数来重复调用rest api的最佳方法是啥