【发布时间】:2021-10-06 16:16:24
【问题描述】:
我的代码运行良好,但每次人们打开硬币活动时,从 coinmarketcap api(名称、符号名称、价格、体积和市值)加载 500 个硬币大约需要 5 秒。我使用facebook shimmer 让人们知道正在加载某些内容,但 5 秒是很多,因为该应用程序在 1 到 2 秒内加载了更多繁重的内容,例如带有图像的 wordpress 数据。但是,这 500 个硬币在 5 秒内并不酷……这是我的代码……
public void getCoinList() {
//posts = 500
ApiInterface apiInterfaceCoin5 =
APIClientCoin.getClient().create(ApiInterface.class);
Map<String, String> params = new HashMap<>();
params.put("limit", posts+"");
Call<CryptoList> call5 = apiInterfaceCoin5.doGetUserListAll(params);
call5.enqueue(new Callback<CryptoList>() {
@Override
public void onResponse(Call<CryptoList> call, Response<CryptoList> response)
{
shimmerFrameLayout.stopShimmer();
shimmerFrameLayout.setVisibility(View.GONE);
swipeRefreshLayout5.setRefreshing(false);
int beforeCoinSize = cryptoList5.size();
CryptoList list5 = response.body();
cryptoList5.addAll(list5.getData());
recyclerView4.setAdapter(adapterCoin5);
}
@Override
public void onFailure(Call<CryptoList> call, Throwable t) {
//Toast.makeText(CryptoListAllCoinActivity.this, "onFailure",
Toast.LENGTH_SHORT).show();
// Log.d("XXXX", t.getLocalizedMessage());
call.cancel();
progressBar3.setVisibility(View.GONE);
shimmerFrameLayout.setVisibility(View.GONE);
swipeRefreshLayout5.setRefreshing(false);
}
});
}
@Headers("X-CMC_PRO_API_KEY: HIDDEN")
@GET("/v1/cryptocurrency/listings/latest")
Call<CryptoList> doGetUserListAll(@QueryMap Map<String, String> params);
适配器:
// Involves populating data into the item through holder
// binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int
position) {
// Get the data model based on position
Datum datum = mData.get(position);
//load coin icon
//if the link doesn't work then you have to upload it into
your own server
Glide.with(context)
.load(new
StringBuilder
("https://s2.coinmarketcap.com/static/img/coins/64x64/")
.append(datum.getId())
.append(".png").toString())
.placeholder(R.drawable.money_icon).into(holder.coin_icon);
Glide.with(context)
.load(new
StringBuilder
("https://s3.coinmarketcap.com/generated/
sparklines/web/7d/usd/")
.append(datum.getId())
.append(".png").toString())
.placeholder(R.drawable.line_24)
.into(holder.sparkline);
TextView symbolName = holder.symbolName;
symbolName.setText(datum.getSymbol());
// Set item views based on your views and data model
TextView name = holder.name;
name.setText(datum.getName());
TextView price = holder.price;
TextView priceDetails = holder.priceDetails;
TextView marketCap = holder.marketCap;
marketCap.setText("$" +
formatNumber(datum.getQuote().getUSD().getMarketCap()));
ImageView coin_icon = holder.coin_icon;
ImageView sparkline = holder.sparkline;
if(datum.getQuote().getUSD().getPrice() >= 1) {
price.setText("$" +
formatNumber(datum.getQuote().getUSD().getPrice()));
}else{
price.setText("$" + String.format("%f",
datum.getQuote().getUSD().getPrice()));
}
TextView textView24h = holder.textView24h;
textView24h.setText(String.format("%.2f",
datum.getQuote().getUSD().getPercentChange24h()) + "%");
if(datum.getQuote().getUSD().getPercentChange24h() <0.000).{
//red
textView24h.setTextColor(Color.parseColor("#EA3943"));
arrowImage.setImageResource(R.drawable.arrow_down);
sparkline.setColorFilter(Color.RED,
PorterDuff.Mode.MULTIPLY);
sparkline.setImageResource(R.drawable.btc_spike);
//changeImageColor(context, sparkline,000);
}else{
//green
textView24h.setTextColor(Color.parseColor("#18C784"));
arrowImage.setImageResource(R.drawable.arrow_up);
sparkline.setColorFilter(Color.GREEN,
PorterDuff.Mode.MULTIPLY);
sparkline.setImageResource(R.drawable.btc_spike);
}
}
Glide.with(context)
.load(new
StringBuilder
("https://s2.coinmarketcap.com/static/img/coins/64x64/")
.append(datum.getId())
.append(".png").toString())
.placeholder(R.drawable.money_icon)
.into(holder.coin_icon);
更新
现在我已经设置了数据库,但不知道如何将数据插入数据库...例如: 我在哪里添加这个:
AppDatabase db =
AppDatabase.getDbInstance(this.getApplicationContext());
//coin object
db.coinDao().insertAllCoins();
在 onResponse 里面?以及如何?
2021 年 8 月 5 日更新:
AppDatabase.class
@Database(entities = {Coins.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract CoinDao coinDao();
private static AppDatabase INSTANCE;
public static AppDatabase getDbInstance(Context context){
if(INSTANCE == null){
INSTANCE = Room
.databaseBuilder(context.getApplicationContext(),
AppDatabase.class,"DB_COIN")
.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
}
币道
@Dao
public interface CoinDao {
@Query("SELECT * FROM coin_table")
List<Coins> getAll();
@Insert
void insertAllCoins(Coins... coins);
@Delete
void delete(Coins coins);
@Update
void updateUsers(Coins... coins);
}
Coins.java
@Entity(tableName = "coin_table")
public class Coins {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo(name = "name")
public String name;
@ColumnInfo(name = "symbol")
public String symbol;
@ColumnInfo(name = "slug")
public String slug;
@ColumnInfo(name = "circulating_supply")
public Double circulatingSupply;
@ColumnInfo(name = "total_supply")
public Double totalSupply;
@ColumnInfo(name = "max_supply")
public Double maxSupply;
@ColumnInfo(name = "date_added")
public String dateAdded;
@ColumnInfo(name = "num_market_pairs")
public Integer numMarketPairs;
@ColumnInfo(name = "cmc_rank")
public Integer cmcRank;
@ColumnInfo(name = "coin_symbol")
public String lastName;
@ColumnInfo(name = "last_updated")
public String lastUpdated;
@ColumnInfo(name = "price")
public Double price;
@ColumnInfo(name = "volume_24h")
public Double volume24h;
@ColumnInfo(name = "percent_change_1h")
public Double percentChange1h;
@ColumnInfo(name = "percent_change_24h")
public Double percentChange24h;
@ColumnInfo(name = "percent_change_7d")
public Double percentChange7d;
@ColumnInfo(name = "market_cap")
public Double marketCap;
}
2021 年 8 月 6 日更新 基于 Muhammad Shuja 的回答 对于 CoinRepository,我收到此错误:
但如果我将其更改为 CriptoList,那么它会说它需要一个 List,哈哈……知道为什么吗?
请注意,我使用带有 s 的 Coins,因为那是类名。
如果我把它改成 CriptoList 它会说这个
coinDao.insertAll(response.body());
需要一个列表
我有我的public getCoinList() 一点供参考,以了解我目前如何从 api 获取数据。
而且,是的,我想每 1 次更新一次数据……就像我想进行一次 api 调用并每 1 分钟更新一次数据一样。谢谢ssssssssssssss
【问题讨论】:
-
我建议在完成不同步骤时添加一个计时器和记录时间,这样您就可以缩小搜索范围,然后可以用您的发现更新您的问题,以便我们为您提供帮助轻松
-
我经常使用外部 API,我通常避免在用户交互时直接访问 API 服务器(除非它不是获取 - 即发布、删除、更新等)。我通常在后台以不同的时间间隔运行一堆作业,并将数据存储在某个地方(数据库、文件等),然后通过我自己的 API 使其可用。当您有 500 个用户同时登录并同时访问市值服务器时,您会很快意识到一次获取数据、存储数据并根据需要随时访问数据更有意义。自己的服务器。
-
@HanletEscaño 是的,我很乐意这样做,你能提供一些代码吗?另外,你能告诉我数据库中的数据将如何更新吗?就像...它会每x次调用一次api?或者是其他东西。另外,我想获得 3,000 多个硬币......所以你的解决方案可以救我
-
@Maduro 我无法提供代码,但概念很简单。对于我拥有的每项工作,我将响应保存在我的数据库中的方式与我得到它的方式完全相同(尽管我通常将 JSON 序列化/反序列化为对象,然后将它们移动到我的数据库)。然后,我不是每次用户需要这些数据时都调用 API,而是直接从我的数据库中获取数据。您更新数据的频率取决于您和您的需求。我的作业需要从每 5 秒运行一次到每天一次到每月一次,这真的取决于。
-
听起来棒极了!你能至少发一个教程吗?我只是在寻找一些关键字,看看你需要什么......