خطا در زمان parseکردن اطلاعات در رتروفیت و retrofit adapter RxJava

0 امتیاز
43 بازدید
سوال شده 14 اردیبهشت 1398 توسط android  

سلام وقت بخیر

مهندس من یک پروژه RSS رو دارم پیش میبرم که به مشکلی برخوردمواسه parseشدن اطلاعات.

دارم از کتابخانه رتروفیت و retrofit adapter RxJva استفاده میکنم که اطلاعات رو با Observable منتشر میکنه ولی ظاهرا رتروفیت اطلاعاتا رو پارس میکنه که آرایه ای از جیسون باشه ولی واسه من جیسون آبجکت هست و به همین خاطر ارور زیر رو میده 

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

چجور میتونم جیسونم رو به آرایه تبدیل کنم .

 

این کلاس مدل من هستش:

 

package com.example.piecesnews.model

import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.databinding.library.baseAdapters.BR

data class DailyNewsModel(
    val imgNews: String, val titleNews: String, val shortNews: String,
    val timeAgo: String, val bookmark: Boolean
) : BaseObservable() {

    @get: Bindable
    var _imgNews: String = imgNews
        set(value) {
            field = value
            notifyPropertyChanged(BR._imgNews)
        }


    @get: Bindable
    var _titleNews: String = titleNews
        set(value) {
            field = value
            notifyPropertyChanged(BR._titleNews)
        }

    @get: Bindable
    var _shortNews: String = shortNews
        set(value) {
            field = value
            notifyPropertyChanged(BR._shortNews)
        }

    @get: Bindable
    var _timeAgo: String = timeAgo
        set(value) {
            field = value
            notifyPropertyChanged(BR._timeAgo)
        }

}

 

اگر لازم بود تا جیسون برگشتی رو هم ارسال کنم براتون

درضمن دارم با کاتلین و معماری mvvm و دیتابایندینگ کد میزنم

این مطلب را به اشتراک بگذارید
دارای دیدگاه 15 اردیبهشت 1398 توسط ASHKARAN  
سلام

لطفا جی سون رو هم ارسال کنید
دارای دیدگاه 15 اردیبهشت 1398 توسط android  
rss رو براتون ایمیل میکنم

1 پاسخ

0 امتیاز
پاسخ داده شده 15 اردیبهشت 1398 توسط ASHKARAN  

پاسخ سرور شما یک JSONOBJECT هست و شما دارید اون رو به JSONARRAY تبدیل می کنید

تقریبا باید به این شکل باشه

Response response = new Gson().fromJson(jsonString , Response.class);

برای تبدیل متن جی سون به کلاس جاوا از پلاگین

Awesome JSON to POJO

استفاده کنید

دارای دیدگاه 15 اردیبهشت 1398 توسط android  
ممنونم ولی چونکه پاسخ یک جیسون بزرگی هستش پلاگین اندروید اون رو تبدیل نمیکنه

استفاده از جیسون رو چجور باید پیاده کنم چون دارم از rxJava استفاده میکنم برای گرفتن دیتا و استفاده از اون
دارای دیدگاه 15 اردیبهشت 1398 توسط ASHKARAN  
لطفا کد قسمت خوندن اطلاعات رو هم بزار
دارای دیدگاه 15 اردیبهشت 1398 توسط android  

از این قسمت درخواست یزنه سرور: 


    @GET("{category}/?json=1")
    fun getDailyNewsList(@Path("category") category: String): Observable<List<DailyNewsModel>>

 

 

 

اینترفیسی برای گرفتن و ذخیره اطلاعات توی دیتابیس:

 


interface RepoDataSource {
    fun fetchNewsRepos(category:String): Observable<List<DailyNewsModel>>

    fun saveRepos(repos: List<DailyNewsModel>)
}

 

 

اینجا از اون اینترفیس استفاده کردم و به وسیله خذسثقرشذمث درخواست سرور رو صدا زدم:

 

 


object RemoteDataSource: RepoDataSource{
    val service = ServiceBuilder.buildService(RepoService::class.java)


    override fun fetchNewsRepos(category: String): Observable<List<DailyNewsModel>> {
        val observable = service.getDailyNewsList(Const.DAYLY_NEWS)
  /*      val gson = Gson()
        gson.fromJson(observable as String, DailyNewsModel::class.java)*/
        return observable

    }

    override fun saveRepos(repos: List<DailyNewsModel>) {

    }



}

 

این هم کلاس رپوزیتوری که دیتا رو از اینترفیس قبلی میخونه  و یکی یکی اونا رو توی دیتابیس ذخیره میکنه که البته کد دیتابیس رو نزدم هنوز:

 

class Repository(val remoteDataSource: RemoteDataSource, val localDataSource: LocalDataSource): RepoDataSource {
    override fun fetchNewsRepos(category: String): Observable<List<DailyNewsModel>> {

        return Observable.concat(localDataSource.fetchNewsRepos(DAYLY_NEWS),
            remoteDataSource.fetchNewsRepos(DAYLY_NEWS)
                .doOnNext { saveRepos(it) }
                .onErrorResumeNext(Observable.empty())

        )

    }

    override fun saveRepos(repos: List<DailyNewsModel>) {
        localDataSource.saveRepos(repos)

    }

}

 

این هم کد کلاس viewModel که دیتا رو از کلاس رپوزیتوری میگیره:

 

class DailyNewsTabFragViewModel : ViewModel() {
    val compositeDisposable = CompositeDisposable()
    val repoLiveData = MutableLiveData<List<DailyNewsModel>>()
    val repository = Repository(RemoteDataSource , LocalDataSource)



    fun getDataRepos(category: String){
        if (repoLiveData.value !=null){
            return
        }
        val reposDisposable = repository.fetchNewsRepos(category)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { message -> repoLiveData.value = message },
                { error -> displayError(error) }
            )



        compositeDisposable.add(reposDisposable)

    }


    fun getLiveData(): LiveData<List<DailyNewsModel>> = repoLiveData

    fun displayError(error: Throwable) {
        Log.e(TAG, "Error while doing something", error)
    }


    override fun onCleared() {
        super.onCleared()
        compositeDisposable.clear()
    }


    companion object{
        val TAG: String = DailyNewsTabFragViewModel::class.java.simpleName
    }
}

 

 

و در نهایت کد فرگمنت که دیتا رو ازویومدل میگیره

 

class DailyNewsTabFragment : Fragment(), DailyNewsTabAdapter.OnItemClickListener {

    lateinit var binding: FragmentDailyNewsTabBinding
    lateinit var dailyNewsTabFragViewModel: DailyNewsTabFragViewModel
    var dailyNewsTabAdapter: DailyNewsTabAdapter = DailyNewsTabAdapter(this)

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_daily_news_tab, container, false)
        val view = binding.root

        setupRecyclerView(view)
        return view
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        initViewModel()

    }
    private fun initViewModel() {
        dailyNewsTabFragViewModel = ViewModelProviders.of(this).get(DailyNewsTabFragViewModel::class.java)
        binding.apply {
            viewModel = dailyNewsTabFragViewModel

        }

        getDailyNewsRepos(dailyNewsTabFragViewModel)
        observeMyDatas(dailyNewsTabFragViewModel)

    }

    private fun setupRecyclerView(view: View) {
        val layoutManager = LinearLayoutManager(this.context)
        view.repository_rv.layoutManager = layoutManager
        view.repository_rv.adapter = dailyNewsTabAdapter
    }

    override fun onItemClick(position: Int) {

        toast(position.toString())
    }


    fun getDailyNewsRepos(viewModel :DailyNewsTabFragViewModel){
        viewModel.getDataRepos(Const.DAYLY_NEWS)
    }

    fun observeMyDatas(viewModel:DailyNewsTabFragViewModel){
        viewModel.getLiveData().observe(this, Observer {
                repos -> dailyNewsTabAdapter.setData(repos)
        })
    }
}

 

 

کلاس مدل رو هم که دیروز ارسال کردم خدمتتون و همینطور RSS رو

972 سوال

817 پاسخ

1,319 دیدگاه

1,271 کاربر

متاسفانه نیستم

این مطلب را به اشتراک بگذارید

ali.ashkaran@gmail
ما .....
  • سعی بر پاسخگویی به سوالات دیگران داریم.
  • به سوال و یا نظر دیگران احترام می گذاریم .
  • این وبسایت را به دیگران معرفی می کنیم.
  • همواره صمیمیت و ادب را رعایت می کنیم.
  • به سوالمان برچسب های مرتبط اضافه می کنیم.
  • در حین طرح سوال فرد خاصی را مخاطب قرار نمی دهیم .
...