android - OkHttp3 响应在 android 的自定义适配器类中显示错误
问题描述
我正在使用 OkHttp3 从服务器获取数据我有自定义适配器类,其中我在单击按钮时在回收器视图项中有一个按钮我正在向服务器发送请求并获得响应。
但是在得到回复时,我收到了错误:
2020-02-14 23:23:23.222 10597-12522/com.example.aamkuconnect E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.example.aamkuconnect, PID: 10597
java.lang.ClassCastException: androidx.multidex.MultiDexApplication cannot be cast to com.example.aamkuconnect.AdminNewOrders
下面是我的代码:
AdminNewOrders.class
public class AdminNewOrders extends AppCompatActivity {
RecyclerView adminSeeOrder;
ProgressBar my_prog;
AdminSeeNewOrderAdapter adapter;
List<AdminSeeNewOrderModel> list = new ArrayList<>();
private static final String URL = "https://www.example.com";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_new_orders);
ActionBar ab = getSupportActionBar();
assert ab!= null;
ab.setTitle("New orders");
ab.setDisplayHomeAsUpEnabled(true);
my_prog = findViewById(R.id.my_prog);
adminSeeOrder = findViewById(R.id.adminSeeOrder);
adminSeeOrder.setHasFixedSize(true);
adminSeeOrder.setLayoutManager(new LinearLayoutManager(this));
newOrders();
}
private void newOrders(){
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
RequestBody formBody = new FormBody.Builder()
.add("order_status","pending")
.build();
Request request = new Request.Builder().post(formBody).url(URL).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONArray jsonArray = new JSONArray(response.body().string());
if(jsonArray.length() > 0){
my_prog.setVisibility(View.INVISIBLE);
for(int i = jsonArray.length()-1;i>-1;i--){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String str1 = jsonObject.getString("name");
AdminSeeNewOrderModel model = new AdminSeeNewOrderModel(str1);
list.add(model);
}
adapter = new AdminSeeNewOrderAdapter(list,getApplicationContext());
adminSeeOrder.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
my_prog.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
});
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
Intent i = new Intent(AdminNewOrders.this,Dashboard.class);
startActivity(i);
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
AdminSeeNewOrderAdapter.class
public class AdminSeeNewOrderAdapter extends RecyclerView.Adapter<AdminSeeNewOrderAdapter.ViewHolder> {
List<AdminSeeNewOrderModel> list = new ArrayList<>();
Context context;
private static final String URL = "https://example.com";
public AdminSeeNewOrderAdapter(List<AdminSeeNewOrderModel> list, Context context) {
this.list = list;
this.context = context;
}
@NonNull
@Override
public AdminSeeNewOrderAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.admin_see_new_order_row,parent,false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull final AdminSeeNewOrderAdapter.ViewHolder holder, final int position) {
final AdminSeeNewOrderModel model = list.get(position);
holder.adSeeName.setText(model.getName());
holder.accept.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
acceptOrders(position);
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView adSeeName,adSeeDate,adSeePhone,adSeeAdr,prodName,prodCost,viewDetails,accept,cancel;
public ViewHolder(@NonNull View itemView) {
super(itemView);
TextView adSeeName = itemView.findViewById(R.id.adSeeName);
Textview accept = itemView.findViewById(R.id.accept);
}
}
private void acceptOrders(String mobile, String product, String date, final int position){
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
RequestBody formBody = new FormBody.Builder()
.add("phone",mobile)
.add("date",date)
.add("product",product)
.build();
Request request = new Request.Builder().post(formBody).url(URL).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
((AdminNewOrders)context).runOnUiThread(new Runnable() {
@Override
public void run() {
try {
String resp = response.body().string();
if(resp.equals("Updated successfully")){
list.remove(position);
notifyItemRemoved(position);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
((AdminNewOrders)context).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
构建.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.aamkuconnect"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
testImplementation 'junit:junit:4.12'
implementation 'com.google.firebase:firebase-analytics:17.2.0'
implementation 'com.google.firebase:firebase-auth:19.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
implementation 'androidx.multidex:multidex:2.0.1'
}
apply plugin: 'com.google.gms.google-services'
有人请让我知道如何解决此错误。任何帮助将不胜感激。
谢谢
解决方案
我可以告诉你很多事情为什么会发生:
- 适配器不应进行 http 调用
- 适配器不应进行 ui 调用(Toast.makeText ...)
还有其他方法可以在不调用 runOnUiThread 的情况下返回 ui 线程,例如
new Handler(Looper.getMainLooper()).post(new Runnable { override void run(){ Toast.makeText... } });
但是你的主要问题是,你提供的上下文是一个应用程序上下文,并且没有附加到任何 UiThread,如果你仍然想这样做,你需要传递 Activity 上下文,甚至确保上下文仍然有效。
改变这个:
adapter = new AdminSeeNewOrderAdapter(list,getApplicationContext());
对此:
adapter = new AdminSeeNewOrderAdapter(list, AdminNewOrders.this);
它会起作用的。
推荐阅读
- css - 单击期间更改样式
- javascript - html to canvas 不截图背景
- reactjs - 尝试在反应中使用“img”标签显示图像时发生错误
- azure-service-fabric - Azure Service Fabric - 从 Service Fabric Explorer 安装以前版本的应用程序?
- loops - Common Lisp中等价的有序对循环
- mysql - 为什么第二次插入给我的表不存在
- python - 它告诉我“预期有缩进块”有人可以帮助我吗?
- reactjs - Docker:绑定挂载没有像我预期的那样工作
- javascript - 使用javascript从数据库中删除
- java - 如何在java中的函数内声明参数以接收像python self这样的图像?