I want to pull crypto data with the retrofit library using the view model and live data functions, but I am getting the following error, I would be very grateful if you could help.
The part that builds the retrofit structure :
object RetrofitInstance {
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl ( BASE_URL )
.addConverterFactory ( GsonConverterFactory.create() )
.build()
}
val api: ApiTerminal by lazy {
retrofit.create ( ApiTerminal::class.java )
}
}
Interface part in this project :
interface ApiTerminal {
#GET("currencies/ticker")
suspend fun getPost ( #Query("key") key : String ): Response<ArrayList<CoinModel>>
}
The repository part in this project :
class Repository {
suspend fun getPost( key : String ) : Response<ArrayList<CoinModel>> {
return RetrofitInstance.api.getPost ( key )
}
}
The part in the project where the view model function is determined :
class MainViewModel ( private val repository: Repository ) : ViewModel() {
val response = MutableLiveData<Response<ArrayList<CoinModel>>>()
fun getPost ( key : String ) {
viewModelScope.launch {
response.value = repository.getPost ( key )
}
}
}
This part of the project is the activity area :
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModelFactory = MainViewModelFactory ( Repository() )
val txt = findViewById<TextView>(R.id.txt)
txt.setOnClickListener {
val viewModel = ViewModelProvider(this, viewModelFactory )[MainViewModel::class.java]
viewModel.getPost("this part contains api key")
viewModel.response.observe(this, Observer {
if (it.isSuccessful) {
txt.text = it.body()?.get(0)?.currency
}
})
}
}
}
The error I got :
2022-04-24 22:01:28.638 5834-5834/com.rk.quex E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.rk.quex, PID: 5834
java.lang.IllegalArgumentException: Unable to create call adapter for class java.lang.Object
for method ApiTerminal.getPost
at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:752)
at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:237)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:162)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:147)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy1.getPost(Unknown Source)
at com.rk.quex.repository.Repository.getPost(Repository.kt:11)
at com.rk.quex.MainViewModel$getPost$1.invokeSuspend(MainViewModel.kt:19)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at com.rk.quex.MainViewModel.getPost(MainViewModel.kt:17)
at com.rk.quex.MainActivity.onCreate$lambda-1(MainActivity.kt:24)
at com.rk.quex.MainActivity.$r8$lambda$hFYFqoAo62q-drAqh-AGqF7aib8(Unknown Source:0)
at com.rk.quex.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:6)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class java.lang.Object.
Tried:
* retrofit2.ExecutorCallAdapterFactory
at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241)
at retrofit2.Retrofit.callAdapter(Retrofit.java:205)
at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:235)
... 32 more
Can you please try the following:
Please share which Retrofit version dependencies you are using.
Launch the getPost Coroutine in the IO thread:
viewModelScope.launch(Dispatchers.IO) {
//code
}
Please try to parse the body in the Repository, to get closer to MVVM principles, the ideal would be to create an event response sealed class, to be able to animate the UI depending on the Response, but I won't confuse you and I will make 2 examples, one without the event response and one with:
class Repository {
suspend fun getPost( key : String ) : ArrayList<CoinModel>? {
val response = RetrofitInstance.api.getPost(key)
return if(response.isSuccessful){
response.body?.let { arrayList ->
arrayList
} ?: run {
null
}
} else {
null
}
}
}
Example with event response sealed class:
sealed class Result <out T> {
data class Error <T> (val message: Exception?): Result<T>()
data class Success <T> (val data: T): Result<T>()
}
class Repository {
suspend fun getPost(key: String): Result<List<CoinModel>> {
return try {
val response = RetrofitInstance.api.getPost(key)
if (response.isSuccessful){
response.body()?.let { coinModelList ->
return#let Result.Success(coinModelList)
} ?: run {
Result.Error(Exception("The body is empty"))
}
} else {
Result.Error(Exception("Response not successful"))
}
} catch (e: Exception) {
Result.Error(Exception("Network error"))
}
}
}
This is how it would be from your viewModel:
class MainViewModel ( private val repository: Repository ) : ViewModel() {
val response = MutableLiveData<List<CoinModel>>()
fun getPost ( key : String ) {
viewModelScope.launch(Dispatchers.IO) {
when(val result = repository.getPost ( key )){
is Result.Error -> //Handle your error logic. You can access the Exception message with result.message
is Result.Success -> response.postValue(result.data)
}
}
}
}
Please keep in mind I wrote it "on-hand". I hope it helps :D
Related
I'm trying to instanciate a Room database in my main activity in Android Studio, following codelabs and tutorials, but my app always crash. Here's a part of the code:
My database (AppDatabase.kt):
#Database(entities = [Device::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun deviceDao(): DeviceDao
companion object {
#Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"item_database"
)
.fallbackToDestructiveMigration()
.build() // <---- The crash occurs here
INSTANCE = instance
return instance
}
}
}
}
And here's the activity from which I'm trying to instantiate it:
class NavigationActivity() : AppCompatActivity() {
private lateinit var binding: ActivityNavigationBinding
private val db by lazy { AppDatabase.getDatabase(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNavigationBinding.inflate(layoutInflater)
setContentView(binding.root)
Log.d("instantiation", "$db") // <----- Called from here
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_navigation)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_devices, R.id.navigation_logs, R.id.navigation_settings
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
}
Finally, here's the error message, which doesn't helps me much:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Package.getName()' on a null object reference
at androidx.room.Room.getGeneratedImplementation(Room.java:82)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1486)
at AppDatabase$Companion.getDatabase(AppDatabase.kt:24)
I tried a lot of things, including ViewModel, Repository and more, but got the crash systematically, at the same point.
Here's also the part of my build.gradle file where I import Room, maybe I'm wrong in some version or whatever...
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android'
id 'kotlin-kapt'
}
[...]
def roomVersion = "2.4.2"
implementation("androidx.room:room-runtime:$roomVersion")
kapt("androidx.room:room-compiler:$roomVersion")
implementation "androidx.room:room-ktx:$roomVersion"
Make sure package declaration on top of the class is declared, for example:
package com.macrosystems.clean.ui.core.view
import android.content.Context
import android.content.Intent
import android.graphics.Color
etc...
I am struggling to use Live data on an MVVM pattern. The app is supposed to:
Fetch data from an API (which it does correctly)
Store that data in the Live data object from the ViewModel
Then the fragment calls the Observer method to fill the recyclerView.
The problem comes in point 3, it does nothing, and I cannot find the solution.
Here is the relevant code. (If I'm missing something, I will try to answer as quickly as possible)
Main Activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Custom button to fetch data from api and log the Live Data value.
binding.refreshFab.setOnClickListener {
viewModel.fetchPlayerData()
Log.d("gabs", "${viewModel.livePlayerlist.value}")
}
}
}
ViewModel:
class SharedViewModel(app: Application): AndroidViewModel(app) {
// val playerDao = LaRojaDB.getDatabase(app).playerDao()
lateinit var playerList: Players
val livePlayerlist: MutableLiveData<MutableList<Players.PlayersItem>> by lazy {
MutableLiveData<MutableList<Players.PlayersItem>>()
}
fun fetchPlayerData() {
CoroutineScope(Dispatchers.IO).launch {
val response = MyService.getLaRojaService().getAllPlayers()
withContext(Dispatchers.Main) {
if (response.isSuccessful) {
val body = response.body()
if(!body.isNullOrEmpty()){
playerList = body
val playerArrayList = mutableListOf<Players.PlayersItem>()
playerList.forEach {
playerArrayList.add(it)
}
livePlayerlist.value = playerList
}
}
}
}
}
}
The fragment that displays the recycler view: (Fragment is already showing, I set up a textView as a title to make sure since I'm new using fragments as well.)
class PlayerListFragment : Fragment() {
private var _binding: FragmentPlayerListBinding? = null
private val binding get() = _binding!!
private val model: SharedViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentPlayerListBinding.inflate(inflater, container, false)
binding.rvPlayerList.layoutManager = LinearLayoutManager(activity)
----> // This is the observer that does not update the UI** <----
model.livePlayerlist.observe( viewLifecycleOwner, {
binding.rvPlayerList.adapter = PlayerAdapter(it)
})
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_player_list, container, false)
}
}
Thank you all in advance, hope I can finally learn what is causing the issue!
I think you don't need to switch Coroutine contexts. A few changes I'd expect if I were reviewing this code:
This should all be in the same IO context. You then postValue to your liveData.
fun fetchPlayerData() {
viewModelScope.launch(Dispatchers.IO) {
val xx = api.fetch()
...
_playerState.postValue(xx) //see below
}
}
Additionally, it's preferred not to expose mutable state, so your ViewModel should not expose the MutableLiveData (which shouldn't really be lazy). But it's also better to encapsulate the state in a sealed class:
//delete this
val livePlayerlist: MutableLiveData<MutableList<Players.PlayersItem>> by lazy {
MutableLiveData<MutableList<Players.PlayersItem>>()
}
Should be: (names are just pseudo code, I have no idea what this code is about)
sealed class PlayerDataState {
data class ListAvailable(data: List<Players.PlayersItem>>): PlayerDataState
object Loading(): PlayerDataState
}
And your new LiveData:
private val _playerState = MutableLiveData<PlayerDataState>()
val playerState: LiveData<PlayerDataState>() get() = _playerState
Finally when observing from the UI, you just...
model.playerState.observe(viewLifecycleOwner, {
when (it) {
is Loading -> ...
is ListAvailable -> binding.rvPlayerList.adapter = PlayerAdapter(it.data)
}
}
I am new with MVVM in kotlin, I want to fetch some data using retrofit and show this in textview but I can't fetch this. In this app first time, I am using the android jetpack component. I tried a lot of times but I can't solve this error. My code in below
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val repository = Repository()
val viewModelFactory = MainViewModelFactory(repository)
viewModel = ViewModelProvider(this, viewModelFactory).get(MainViewModel::class.java)
viewModel.getEmployeeData()
viewModel.repoResponse.observe(this, Observer { response ->
if (response.isSuccessful) {
Log.d("Response", response.body()?.employee_id.toString())
Log.d("Response", response.body()?.employee_name.toString())
Log.d("Response", response.body()?.employee_age.toString())
Log.d("Response", response.body()?.employee_salary.toString())
name.text = response.body()?.employee_name!!
} else {
Log.d("Response", response.errorBody().toString())
name.text = response.code().toString()
}
})
}
MainViewModelFactory.kt
class MainViewModelFactory(private val repository: Repository):ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MainViewModel(repository) as T
}
MainViewModel.kt
class MainViewModel(private val repository: Repository):ViewModel() {
val repoResponse:MutableLiveData<Response<Employee>> = MutableLiveData()
fun getEmployeeData(){
viewModelScope.launch {
val response = repository.getEmployeeData()
repoResponse.value = response
}
}
ApiClient.kt
object ApiClient {
private val retrofit by lazy{
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val api:Api by lazy {
retrofit.create(Api::class.java)
}
Api.kt
public interface Api {
#GET("api/v1/employee/1")
suspend fun getEmployeeData():Response<Employee>
}
Repository.kt
class Repository {
suspend fun getEmployeeData():Response<Employee>{
return ApiClient.api.getEmployeeData()
}
Employee.kt
data class Employee(
#SerializedName("id")
var employee_id: Int,
#SerializedName("employee_name")
var employee_name: String,
#SerializedName("employee_age")
var employee_age: Int,
#SerializedName("employee_salary")
var employee_salary: Int
)
Constants.kt
class Constants {
companion object{
const val BASE_URL = "http://dummy.restapiexample.com"
}
Error image
How can i solve this? please help me. Thank you
Retrofit only supports suspend keyword since 2.6.4, so using 2.3.0 won't work.
You should update to a newer version of Retrofit. The current latest version at the time of writing is 2.9.0.
I am working on Android Application in Which I am getting specific Data from Room Database by specific path in the Storage. My App Got Crashes as It does not have Any Data in the Storage and the Logcat gives me this..
java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:154)
at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:135)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:195)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:428)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:145)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:106)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
at com.maximus.technologies.views.activities.scanneddatabase.TodoDaoScanned_Impl.getAllScan(TodoDaoScanned_Impl.java:152)
at com.maximus.technologies.views.fragments.scanhistorypackage.QRRetrievingScanClassPresenter$getAllDatFromDatabase$1.invokeSuspend(QRRetrievingScanClassPresenter.kt:29)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
The Above Error or crash Only occurs as the app dont have any data in Storage. But as I put a Data the Crash Problem Get Resolved.
I am not able to Understand what the Problem actually is...
Here is My Room Database Class..
#Database(
entities = [TodoEntity::class,TodoEntityScanned::class],
version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun TodoDao(): TodoDao
abstract fun TodoDaoScanned(): TodoDaoScanned
object DatabaseBuilder {
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase {
if (INSTANCE == null) {
synchronized(AppDatabase::class) {
INSTANCE = buildRoomDB(context)
}
}
return INSTANCE!!
}
private fun buildRoomDB(context: Context) =
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"mindorks-example-coroutines"
).build()
}
}
Room Database Retrieving Interface where app Crashes on getall()
override fun getAllDatFromDatabase(appDatabasescanned: AppDatabase) {
var list = listOf<TodoEntityScanned>()
try {
GlobalScope.launch(Dispatchers.Default) {
list = appDatabasescanned.TodoDaoScanned().getAllScan()
Log.d("hello","hello")
mView.showAllData(list)
}
}
catch (e:Exception){
Log.d("get hello",e.toString())
}
}
The getAll lies in Dao Class
interface TodoDao {
#Query("SELECT * FROM tablefilepaths")
fun getAll(): List<TodoEntity>
#Query("SELECT * FROM tablefilepaths WHERE imagespath LIKE :title")
fun findByTitle(title: String): TodoEntity
#Insert
fun insertpaths(todo: TodoEntity)
#Delete
fun deletepaths(todo: TodoEntity)
#Query("DELETE FROM tablefilepaths WHERE id = :noteId")
fun deleteNoteById(noteId: Int)
#Update
fun updateTodo(vararg todos: TodoEntity)}
Here is My Fragment Class Where I am Setting data in RecyclerView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerviewcreatehistory?.layoutManager = LinearLayoutManager(context)
recyclerviewcreatehistory?.setHasFixedSize(true)
filefetch()
customAdaptercreatehistory = CustomAdapterCreateHistory(this.context ?: return, charItemcreate!!,this)
recyclerviewcreatehistory?.adapter = customAdaptercreatehistory
}
fun filefetch() {
val noteDatabase: AppDatabase = AppDatabase.DatabaseBuilder.getInstance(requireContext())
retrivingpresenter = QRRetrievingClassPresenter(this)
retrivingpresenter!!.getAllDatFromDatabase(noteDatabase)
}
override fun showAllData(note_list: List<TodoEntity>) {
if (note_list is ArrayList<*>) {
val arraylist = note_list as ArrayList<TodoEntity>
charItemcreate=arraylist
}
if (charItemcreate.isEmpty()){
}else{
customAdaptercreatehistory?.updateUsers(note_list as ArrayList<TodoEntity>)
customAdaptercreatehistory?.notifyDataSetChanged()
// Log.d("hello", note_list[0].imagesPathData)
}
}
You have to do some checks in your getAllDatFromDatabase() inside your coroutine. I guess list variable equals null or something like that. You should check if there are any files and if not you need to put there something else.
I created my app and the app is working correctly in debug mode.after obfuscating a part of application that get codes list and shows in recyclerview not working properly
in this fragment I am going to get the codes list-codes is my parcelable models class-but the main thread lock and nothing works
I tried to prevent obfuscate this class but it still does not work correctly.
I cant debug my released app to find the problem
please help me to find problem or debug the released apk
this is my codes:
the codes model class:
class Codes(
#SerializedName("id")
var id: String?,
#SerializedName("title")
var title: String?,
#SerializedName("text")
var text: String?,
#SerializedName("codes")
var codes: String?,
#SerializedName("date")
var date: String?,
#SerializedName("codeId")
var codeId: String?,
#SerializedName("point")
var point: Int,
#SerializedName("name")
var name: String?,
#SerializedName("family")
var family: String?,
#SerializedName("image")
var image: String?,
#SerializedName("jensiat")
var jensiat: Int
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readInt(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readInt()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(id)
parcel.writeString(title)
parcel.writeString(text)
parcel.writeString(codes)
parcel.writeString(date)
parcel.writeString(codeId)
parcel.writeInt(point)
parcel.writeString(name)
parcel.writeString(family)
parcel.writeString(image)
parcel.writeInt(jensiat)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Codes> {
override fun createFromParcel(parcel: Parcel): Codes {
return Codes(parcel)
}
override fun newArray(size: Int): Array<Codes?> {
return arrayOfNulls(size)
}
}
}
codes fragment(where I get the List and show in recyclerview):
viewModel.getAllCodes(SORT_POPULAR).observe(this, Observer {
myList = it
Utils.customAnimation(recycler, animation = Techniques.Landing)
codeAdapter = CodeAdapter(context!!, it) { codeId, position ->
Log.i("LOG","code id:$codeId and position is: $position")
var transaction = activity!!.supportFragmentManager.beginTransaction()
lastPosition = position
var detailCodeFragment = DetailCodeFragment {
codeAdapter.changePoint(it)
}
var selectedCode: Codes? = null
for (i in 0 until myList.size) {
var id = myList[i].codeId
if (id == codeId) {
selectedCode = myList[i]
}
}
var bundle = Bundle()
bundle.putParcelable("codes", selectedCode)
bundle.putInt("position", lastPosition)
detailCodeFragment.arguments = bundle
Utils.customAnimation(
activity!!.findViewById(R.id.main_fragment_frame),
animation = Techniques.SlideInRight
)
transaction.add(R.id.main_fragment_frame, detailCodeFragment)
transaction.addToBackStack(null)
transaction.commit()
}
recycler.adapter = codeAdapter
loadingFragme.visibility = View.GONE
})
}
proguard rules:
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class * implements android.os.Parcelable {
public static final <fields>;
}