android - 当我尝试重新加载活动时,尝试在空对象引用上调用虚拟方法 xx
问题描述
我有一个从 mySql db 加载一些数据以填充 Recyclerview 的活动。
PollActivity.java(相关代码)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_poll);
rv = findViewById(R.id.rv);
// *** Rv Init ***
LinearLayoutManager llm = new LinearLayoutManager(this);
rv.setLayoutManager(llm);
rv.setHasFixedSize(false);
polls = new ArrayList<>();
// SqLite data management
db = new SQLiteHandler(getApplicationContext());
HashMap<String, String> user = db.getUserDetails();
final String userid = user.get("uid");
// Local data
String localBefore = Locale.getDefault().getLanguage().toUpperCase();
final String local;
switch (localBefore){
case "IT":
local = "IT";
break;
case "FR":
local = "FR";
break;
case "DE":
local = "DE";
break;
case "ES":
local = "ES";
break;
default:
local = "EN";
break;
}
// ************
// *** MAIN ***
// ************
// Tag used to cancel the request
String tag_string_req = "req_login";
MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
.title(R.string.strDialogProgressLoading_title)
.content(R.string.strDialogProgressReg_desc)
.progress(true, 0);
final MaterialDialog myDialog = builder.build();
myDialog.show();
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.POLL_LOADING, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
if (!error) {
for(int i=0; i<jObj.length()-2; i++){
int j = i + 1;
JSONObject pollObject = jObj.getJSONObject("poll" + i);
JSONObject pollObjectNext = jObj.getJSONObject("poll" + j);
i++;
//Id to String Translate
int idInterests = getResources().getIdentifier("strInterestsItem" + pollObject.getString("id_interests"), "string", getPackageName());
String strInterests = getString(idInterests);
String strPoint;
if(pollObject.getString("sponsor").equals("UUABA")){
strPoint = "+200";
}else{
strPoint = "+150";
}
//String concatenation
String idPoll = "#" + pollObject.getString("id_poll");
String strQuestion = "#" + pollObject.getString("poll_question");
String IdUser = userid;
polls.add(new Poll(idPoll
, pollObject.getString("sponsor")
, pollObject.getString("poll_user_state")
, IdUser
, strInterests
, strQuestion
, pollObject.getString("poll_answer")
, pollObject.getString("id_poll_answer")
, pollObjectNext.getString("poll_answer")
, pollObjectNext.getString("id_poll_answer")
, strPoint));
}
initializeAdapter();
myDialog.dismiss();
} else {
myDialog.dismiss();
// Error in loading. Get the error message
String errorMsg = jObj.getString("error_msg");
int idErrorRes = getResources().getIdentifier(errorMsg, "string", getPackageName());
String strErrorRes = getString(idErrorRes);
//POPUP ERRORE
new MaterialDialog.Builder(PollActivity.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(strErrorRes)
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
myDialog.dismiss();
//POPUP ERRORE
new MaterialDialog.Builder(PollActivity.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(getResources().getString(R.string.errorVolley1) + "(" + error + ")")
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();
}
}) {
@Override
protected Map<String, String> getParams() {
// Posting parameters to loading url
Map<String, String> params = new HashMap<String, String>();
params.put("userid", userid);
params.put("local", local);
//Log.d("NINJA", "UserID: " + userid);
//Log.d("NINJA", "Local: " + local);
return params;
}
};
// Adding request to request queue
AppVolleyController.getInstance().addToRequestQueue(strReq, tag_string_req);
// ************
// ************
// ************
private void initializeAdapter(){
RVAdapter adapter = new RVAdapter(polls);
rv.setAdapter(adapter);
}
public void reloadActivity(){
startActivity(getIntent());
finish();
}
}
RVAdapter.java(我的 Recycler View Adapter)
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PollViewHolder> {
public static class PollViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView txtIdPoll;
ImageView imgSponsor;
ImageView imgNew;
TextView txtIdInterests;
TextView txtQuestion;
RadioGroup radioGroupAnswers;
RadioButton radioAnswer1;
RadioButton radioAnswer2;
Button btnPoint;
PollViewHolder(View itemView) {
super(itemView);
cv = itemView.findViewById(R.id.cv);
txtIdPoll = itemView.findViewById(R.id.txtIdPoll);
imgSponsor = itemView.findViewById(R.id.imgSponsor);
imgNew = itemView.findViewById(R.id.imgNew);
txtIdInterests = itemView.findViewById(R.id.txtIdInterests);
txtQuestion = itemView.findViewById(R.id.txtQuestion);
radioGroupAnswers = itemView.findViewById(R.id.radioGroupAnswers);
radioAnswer1 = itemView.findViewById(R.id.radioAnswer1);
radioAnswer2 = itemView.findViewById(R.id.radioAnswer2);
btnPoint = itemView.findViewById(R.id.btnPoint);
}
}
List<Poll> polls;
//Context context;
public RVAdapter(List<Poll> polls){
this.polls = polls;
//this.context = context;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public PollViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.poll_item, viewGroup, false);
PollViewHolder pvh = new PollViewHolder(v);
return pvh;
}
@Override
public void onBindViewHolder(final PollViewHolder pollViewHolder, final int i) {
final int rb1id = 1000;
final int rb2id = 2000;
//Setting RadioButton ID
pollViewHolder.radioAnswer1.setId(rb1id);
pollViewHolder.radioAnswer2.setId(rb2id);
pollViewHolder.txtIdPoll.setText(polls.get(i).txtIdPoll);
if(polls.get(i).txtSponsor.equals("UUABA")){
pollViewHolder.imgSponsor.setImageResource(R.drawable.ic_logo_red_bg);
}else{
pollViewHolder.imgSponsor.setImageResource(R.drawable.ic_sponsor_green_bg);
}
if(polls.get(i).txtNew.equals("0")){
pollViewHolder.imgNew.setImageResource(R.drawable.ic_new);
}else{
pollViewHolder.btnPoint.setEnabled(false);
pollViewHolder.btnPoint.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP);
}
pollViewHolder.txtIdInterests.setText(polls.get(i).txtIdInterests);
pollViewHolder.txtQuestion.setText(polls.get(i).txtQuestion);
pollViewHolder.radioAnswer1.setText(polls.get(i).txtAnswer1);
pollViewHolder.radioAnswer2.setText(polls.get(i).txtAnswer2);
pollViewHolder.btnPoint.setText(polls.get(i).txtPoint);
pollViewHolder.btnPoint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(pollViewHolder.radioGroupAnswers.getCheckedRadioButtonId() == -1){
Snackbar snackbar = Snackbar.make(v, R.string.strSnackPoll, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView textView =snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.YELLOW);
snackbar.show();
}else{
QueryUtils queryUtils = new QueryUtils();
String IdPoll = String.valueOf((polls.get(i).txtIdPoll)).replace("#", "");
switch (pollViewHolder.radioGroupAnswers.getCheckedRadioButtonId()){
case 1000:
queryUtils.upgPollAnswer(String.valueOf((polls.get(i).txtUserId)), IdPoll, String.valueOf((polls.get(i).txtIdAnswer1)));
break;
case 2000:
queryUtils.upgPollAnswer(String.valueOf((polls.get(i).txtUserId)), IdPoll, String.valueOf((polls.get(i).txtIdAnswer2)));
break;
}
}
}
});
}
@Override
public int getItemCount() {
return polls.size();
}
}
此时,我想在按钮单击时更新 db 字段并重新加载 PollActivity.java 以强制 RecyclerView 更新(我希望 NEW 图像从更新的 CardView 中消失)。我想这样做是调用我的 QueryUtils.java 的方法(它将包含的方法之一),避免在适配器内编写过多的代码。
QueryUtils.java
@SuppressLint("Registered")
public class QueryUtils extends Application {
private String tag_string_req = "req_poll_answer_upg";
public void upgPollAnswer(final String UserId, final String PollId, final String AnswerId){
Log.d("NINJA", "Utente: " + UserId);
Log.d("NINJA", "Poll: " + PollId);
Log.d("NINJA", "Risposta: " + AnswerId);
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.POLL_ANSWER_UPG, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
String message = jObj.getString("message");
if (!error) {
Log.d("NINJA", "Messaggio: " + message);
PollActivity pollActivity = new PollActivity();
pollActivity.reloadActivity();
} else {
//myDialog.dismiss();
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
int idErrorRes = getResources().getIdentifier(errorMsg, "string", getPackageName());
String strErrorRes = getString(idErrorRes);
Log.d("NINJA", "ErrorePhP: " + strErrorRes);
//POPUP ERRORE
/*new MaterialDialog.Builder(QueryUtils.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(strErrorRes)
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();*/
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("NINJA", "ErroreVolley: " + error);
//myDialog.dismiss();
//POPUP ERRORE
/*new MaterialDialog.Builder(QueryUtils.this)
.title(getResources().getString(R.string.strDialogAttention_title))
.titleColor(getResources().getColor(R.color.colorAccentDark))
.content(getResources().getString(R.string.errorVolley1) + "(" + error + ")")
.positiveText(R.string.strDialogBtnPositive)
.contentGravity(GravityEnum.CENTER)
.positiveColor(getResources().getColor(R.color.colorAccent))
.icon(getResources().getDrawable(R.drawable.ic_dialog_alert))
.cancelable(false)
.autoDismiss(false)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(MaterialDialog dialog, DialogAction which) {
dialog.dismiss();
}
})
.show();*/
}
}) {
@Override
protected Map<String, String> getParams() {
// Posting parameters to loading url
Map<String, String> params = new HashMap<String, String>();
params.put("userid", UserId);
params.put("id_poll", PollId);
params.put("id_answer", AnswerId);
return params;
}
};
// Adding request to request queue
AppVolleyController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
}
在更新过程结束时,我调用 PollActivity 中的 reloadActivity 方法来重新加载自身。此调用生成以下错误:
LOGCAT
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
at android.app.Activity.startActivityForResult(Activity.java:4226)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)
at android.app.Activity.startActivityForResult(Activity.java:4183)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:751)
at android.app.Activity.startActivity(Activity.java:4522)
at android.app.Activity.startActivity(Activity.java:4490)
at com.uuaba.uuaba.core.PollActivity.reloadActivity(PollActivity.java:345)
at com.uuaba.uuaba.utils.QueryUtils$1.onResponse(QueryUtils.java:48)
at com.uuaba.uuaba.utils.QueryUtils$1.onResponse(QueryUtils.java:33)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我是 Android 编程新手,我尝试了在这个很棒的论坛中找到的不同解决方案,但没有一个对我有用。
请帮我
解决方案
Problem is that you are trying to create a new instance of activity without the use of intent :
PollActivity pollActivity = new PollActivity();
pollActivity.reloadActivity();
You should replace this code with the following lines:
public void onClickChangeActivity() {
Intent intent = new Intent(this, PollActivity.class);
startActivity(intent);
}
But your solution is far away from the ideal solutions available in the market. Restarting the activity whenever there is a change in data because you have to update data can never be a good way to go. Try considering one of these ways to prevent activity restart
- Create a data stream(list of data) and keep on reading that on activity level.
Create a local broadcast receiver
Do let me know if you need help in above ways.
As a quick fix for the problem you can use this hackish way
Create a callback
interface Result { void success(ResponseModel model); void failure(Throwable throw); }
In QueryUtils
List resultCallbacks = new ArrayList(); public void addCallback(Result result) { resultCallbacks.add(result); }
create List resultCallbacks and a method addCallback
to add the callbacks
- In PollsActivity write this
((QueryApplication)getApplicationContext().getApplication()).addCallbacks(this);
and implement the callback.
On receiving any data update your list and do
RVUpdater.notifyDataSetChanged();
Hope this will help.
推荐阅读
- regex - 在不使用环视的情况下匹配两组字符之间的字符串
- windows - 将 ping 结果保存到 TXT 文件
- c# - 如何使用 EF 和依赖注入在具有相同架构但不同名称的数据库之间进行更改?
- xml - 是否可以使用 Groovy 脚本将“<”和“>”字符直接注入 SoapUI 请求 XML?
- python - 连接两个刺列 - python
- pandas - 使用groupby后如何过滤对象?
- java - 如何优化正则表达式模式?
- flutter - 实际底部溢出123像素意味着什么?
- wordpress - 在 WordPress 中将 codesample 插件添加到 TinyMCE 时出错
- php - preg_match 上的 Css 类单词匹配