I have a fragment in which,I load some data from sever using background thread and update the UI using "runOnUiThread".But it gives me error "fragment not attached to activity".
How can I resolve that issue?
code:-
AsyncTask.execute(new Runnable() {
#Override
public void run() {
/*Checking whether user is loggedin or not*/
if (loginSessionManager.isLogin()) {
/*Creating object of "CServerRequest" class*/
cServerRequest = new CServerRequest(mContext);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject();
jsonObject.put(CRequestKey.AGENT_CODE, m_szMobileNumber.trim());
jsonObject.put(CRequestKey.PIN, m_szEncryptedPassword.trim());
if (BuildConfig.kDebugInfo)
Log.d(TAG, "Request::" + jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.VISIBLE);
}
});
}
String s_szWalletURL = CAPIStorage.IREWARDS_URL + CAPIStorage.WALLET_BALANCE_URL;
cServerRequest.postWalletRequest("POST", s_szWalletURL, jsonObject);
/*Handling server response and error here*/
cServerRequest.setCallBackListener(new CServerRequest.IResult() {
#Override
public void notifySuccess(String requestType, JSONObject response) {
if (BuildConfig.kDebugInfo)
Log.d(TAG, "Response::" + response);
try {
int nResultCodeFromServer = Integer.parseInt(response.getString(CResponseKey.GENERAL_RESULT_CODE));
if (nResultCodeFromServer == ConstantInt.TRANSACTION_SUCCESS) {
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.GONE);
m_walletHeading.setVisibility(View.VISIBLE);
m_SuccessLayout.setVisibility(View.VISIBLE);
}
});
}
String s_szWalletBalance = response.getString(CResponseKey.WALLET_BALANCE).trim();// get wallet balance fro response
String trimwalletBalance = s_szWalletBalance.substring(0, s_szWalletBalance.indexOf("."));// trim waalet balance from response.
CWalletDataModel.getInstance().setS_szWalletBalance(trimwalletBalance);// set wallet balance
// showing wallet balance here from ui thread.
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (m_szCountryCode.equalsIgnoreCase(CResponseKey.COUNTRY_INDIA)) {
m_currency.setText(getString(string.ruppes_symbol));
} else {
m_currency.setText(getString(string.currency_dollar));
}
m_points.setText(CWalletDataModel.getInstance().getS_szWalletBalance());
if (m_szCountryCode.equalsIgnoreCase(CResponseKey.COUNTRY_INDIA)) {
/*If found indian user then show conversion of points in rupees*/
amountConversionIndia();
} else {
/*If found non-indian then will show conversion of points in doller*/
amountConversionInternational();
}
}
});
}
/*Connection lost error*/
} else if (nResultCodeFromServer == ConstantInt.CONNECTION_LOST) {
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_walletHeading.setVisibility(View.GONE);
m_ErrorText.setText(getResources().getString(string.connection_lost));
m_ErrorText.setText(getResources().getString(string.retry));
}
});
}
/*Timed out error from response*/
} else if (nResultCodeFromServer == ConstantInt.TIMED_OUT) {
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_walletHeading.setVisibility(View.GONE);
m_ErrorText.setText(getResources().getString(string.connection_timed_out));
m_ErrorBtn.setText(getResources().getString(string.retry_text));
}
});
}
/*Technical failure response from server*/
} else if (nResultCodeFromServer == ConstantInt.TECHNICAL_FAILURE) {
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_walletHeading.setVisibility(View.GONE);
m_ErrorText.setText(getResources().getString(string.technical_failure));
m_ErrorBtn.setText(getResources().getString(string.retry_text));
}
});
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void notifyError(String requestType, VolleyError error) {
if (BuildConfig.kDebugInfo)
Log.d(TAG, "Error::" + error);
if (isAdded()) {
/*Time out volley error*/
if (error instanceof TimeoutError) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_walletHeading.setVisibility(View.GONE);
m_ErrorText.setText(getResources().getString(string.connection_timed_out));
m_ErrorBtn.setText(getResources().getString(string.retry_text));
}
});
/*Network volley error*/
}
}
if (isAdded()) {
if (error instanceof NetworkError) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_walletHeading.setVisibility(View.GONE);
m_ErrorText.setText(getResources().getString(string.unable_to_connect_text));
m_ErrorBtn.setText(getResources().getString(string.retry));
}
});
}
}
}
});
} else {
if (isAdded()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (isAdded()) {
m_loading_layout.setVisibility(View.GONE);
m_ErrorLayout.setVisibility(View.VISIBLE);
m_ErrorText.setText(mContext.getResources().getString(string.please_log_into_your_account));
m_ErrorBtn.setText(getResources().getString(string.login_btn_text));
}
}
});
}
}
}
});
}
The solution to this problem should be cancel your asynctask in onStop().
You also don't introduce the problem of memory leak.
#Override
public void onStop() {
super.onStop();
mYourAsyncTask.cancel(true);
}
Related
APPSYNC_ERROR: Attempt to invoke virtual method
java.util.Map
com.amazonaws.mobile.client.AWSMobileClientStore.get(java.lang.String[])
on a null object reference
I am trying to inserting data in AWS table, But i got this error.
Can you help me to resolve this issue?
AWSAppSyncClient client = AWSAppSyncClient.builder()
.context(context)
.region(AppHelper.cognitoRegion)
.serverUrl(AppHelper.SERVER_URL)
.cognitoUserPoolsAuthProvider(new CognitoUserPoolsAuthProvider() {
#Override
public String getLatestAuthToken() {
try {
return AWSMobileClient.getInstance().getTokens().getIdToken().getTokenString();
} catch (Exception e){
Log.e("APPSYNC_ERROR", e.getLocalizedMessage());
return e.getLocalizedMessage();
}
}
}).persistentMutationsCallback(new PersistentMutationsCallback() {
#Override
public void onResponse(PersistentMutationsResponse response) {
Log.d("NOTERROR", response.getMutationClassName());
}
#Override
public void onFailure(PersistentMutationsError error) {
Log.e("TAG", error.getMutationClassName());
Log.e("TAG", "Error", error.getException());
}
}).build();
You need to initialize AWSMobileClient successfully before its usage.
AWSMobileClient.getInstance().initialize(getApplicationContext(), new Callback<UserStateDetails>() {
#Override
public void onResult(UserStateDetails userStateDetails) {
switch (userStateDetails.getUserState()){
case SIGNED_IN:
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView textView = (TextView) findViewById(R.id.text);
textView.setText("Logged IN");
}
});
break;
case SIGNED_OUT:
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView textView = (TextView) findViewById(R.id.text);
textView.setText("Logged OUT");
}
});
break;
default:
AWSMobileClient.getInstance().signOut();
break;
}
}
#Override
public void onError(Exception e) {
Log.e("INIT", e.toString());
}
});
If initialize is successful, you will be able to retrieve the tokens through the getTokens() method.
Source: https://aws-amplify.github.io/docs/android/authentication
I have implemented Branch.io referral program.Debug mode is on. When I click on the link it navigates to the app. On signup success i am using setIdentity("user_id") method and then getCredits() and Redeem Credits of referrer and referred user.It works only one or two times on a device then after that, it returns returned{} on setIdentity("user_id").
There is my code:
branch.setIdentity(Settings.USERID, new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (!referrer_id.equalsIgnoreCase("")) {
branch.userCompletedAction("referAFriend");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
branch.loadRewards(new Branch.BranchReferralStateChangedListener() {
#Override
public void onStateChanged(boolean changed, BranchError error) {
if (error == null) {
if (changed) {
credits = branch.getCredits();
Log.e("credits", credits + "");
branch.redeemRewards(credits, new Branch.BranchReferralStateChangedListener() {
#Override
public void onStateChanged(boolean changed, BranchError error) {
branch.logout(new Branch.LogoutStatusListener() {
#Override
public void onLogoutFinished(boolean loggedOut, BranchError error) {
if (loggedOut) {
Log.e("210", loggedOut + "");
if (!referrer_id.equalsIgnoreCase("")) {
Log.e("209",referrer_id+"");
branch.setIdentity(referrer_id, new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
Log.e("215",referringParams+"");
if(referringParams.toString().equalsIgnoreCase("{}"))
{
Utils.resultdialog(SignupActivity.this, "Registered Successfully.", "signup");
}
else {
if (error == null) {
branch.loadRewards(new Branch.BranchReferralStateChangedListener() {
#Override
public void onStateChanged(boolean changed, BranchError error) {
if (error == null) {
if (changed) {
refreepoints = branch.getCredits();
Log.e("refreepoints", refreepoints + "");
branch.redeemRewards(refreepoints, new Branch.BranchReferralStateChangedListener() {
#Override
public void onStateChanged(boolean changed, BranchError error) {
if (error == null) {
if (changed) {
} else {
}
} else {
Log.e("255", "255");
}
}
}
});
}
} else {
Log.e("265", error + "");
Utils.resultdialog(SignupActivity.this, "Registered Successfully.", "signup");
}
}
});
} else {
Log.e("268", error + "");
}
}
}
});
} else {
Log.e("266", "error");
}
}
}
});
}
});
} else {
Log.e("271", error + "");
}
} else {
Log.e("274", error + "");
}
}
});
}
}, 10000);
} else {
}
}
});
In my application I want check internet and when connected load some data, if not connected check data any 5000ms and check this 3 level (15000ms), if in this 15000ms not connected show user "Internet Not Connected" and when connected internet get this data.
My code:
private void retrofitData(boolean isConnect) {
if (isConnect) {
try {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<Retrofit_ColoniesModelResponse> call = apiInterface.getColoniesResponse();
call.enqueue(new Callback<Retrofit_ColoniesModelResponse>() {
#Override
public void onResponse(Call<Retrofit_ColoniesModelResponse> call, Response<Retrofit_ColoniesModelResponse> response) {
try {
if (response != null) {
if (response.body() != null) {
// first remove
models.clear();
// then fill
models.addAll(response.body().getCategories());
mAdaper.notifyDataSetChanged();
colonies_RecyclerView.setAdapter(mAdaper);
CustomProcessDialog.dissmis();
showHelp();
} else {
CustomProcessDialog.dissmis();
new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE)
.setTitleText("title")
.setContentText("message")
.setConfirmText("ok")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
finish();
startActivity(getIntent());
}
})
.show();
}
} else {
CustomProcessDialog.createAndShow(context);
TastyToast.makeText(context, "error", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
checkNetLayout.setVisibility(View.GONE);
} catch (Exception e) {
}
}
#Override
public void onFailure(Call<Retrofit_ColoniesModelResponse> call, Throwable t) {
new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE)
.setTitleText("title")
.setContentText("message")
.setConfirmText("ok")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
finish();
startActivity(getIntent());
}
})
.show();
}
});
} catch (Exception e) {
Log.e("ServerEx", "Error : " + e);
}
} else {
checkNetLayout.setVisibility(View.VISIBLE);
if (mAdaper != null) {
mAdaper.clear();
colonies_RecyclerView.setAdapter(mAdaper);
}
categoryCheckNet_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
}
How can I achieve this? Please help me. I am amateur.
place this method in your Conastant class where you place utility methods:
public abstract static class BackoffCallback<T> implements Callback<T> {
private static int RETRY_COUNT = 3;
private static final double RETRY_DELAY = 5000;
private int retryCount = 0;
protected BackoffCallback(int retryNum) {
RETRY_COUNT=retryNum;
}
#Override
public void onFailure(final Call<T> call, Throwable t) {
retryCount++;
if (retryCount <= RETRY_COUNT) {
int expDelay = (int) (RETRY_DELAY);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
retry(call);
}
}, expDelay);
} else {
onFailedAfterRetry(t);
}
}
private void retry(Call<T> call) {
call.clone().enqueue(this);
}
public abstract void onFailedAfterRetry(Throwable t);
}
And use it in main activity like:
private void retrofitData(boolean isConnect) {
if (isConnect) {
try {
Retrofit_ApiInterface apiInterface = Retrofit_ApiClient.getClient().create(Retrofit_ApiInterface.class);
Call<Retrofit_ColoniesModelResponse> call = apiInterface.getColoniesResponse();
call.enqueue(new Constants.BackoffCallback<Retrofit_ColoniesModelResponse>(3) {
#Override
public void onResponse(Call<Retrofit_ColoniesModelResponse> call, Response<Retrofit_ColoniesModelResponse> response) {
try {
if (response != null) {
if (response.body() != null) {
// first remove
models.clear();
// then fill
models.addAll(response.body().getCategories());
mAdaper.notifyDataSetChanged();
colonies_RecyclerView.setAdapter(mAdaper);
CustomProcessDialog.dissmis();
showHelp();
} else {
CustomProcessDialog.dissmis();
new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE)
.setTitleText("title")
.setContentText("message")
.setConfirmText("ok")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
finish();
startActivity(getIntent());
}
})
.show();
}
} else {
CustomProcessDialog.createAndShow(context);
TastyToast.makeText(context, "error", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
checkNetLayout.setVisibility(View.GONE);
} catch (Exception e) {
}
}
#Override
public void onFailedAfterRetry(Throwable t) {
new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE)
.setTitleText("title")
.setContentText("message")
.setConfirmText("ok")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
finish();
startActivity(getIntent());
}
})
.show();
}
});
}
} else {
checkNetLayout.setVisibility(View.VISIBLE);
if (mAdaper != null) {
mAdaper.clear();
colonies_RecyclerView.setAdapter(mAdaper);
}
categoryCheckNet_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loadData();
}
});
}
}
I need to save in Realm a JSON that I've saved in Assets folder.
So I've decided to do it in this way:
private void putCountryIntoRealm()
{
Observable.create(new Observable.OnSubscribe<String>()
{
public void call(Subscriber<? super String> subscriber)
{
try
{
InputStream is = getActivity().getAssets().open("countries.json");
Reader inRead = new InputStreamReader(is);
Gson gson = new Gson();
JsonReader reader = new JsonReader(inRead);
reader.setLenient(true);
reader.beginArray();
while (reader.hasNext())
{
CountryObject ct = gson.fromJson(reader, CountryObject.class);
country.add(ct);
System.out.println("size ct: "+country.size());
subscriber.onNext(reader.toString());
}
reader.endArray();
reader.close();
subscriber.onCompleted();
}
catch (IOException e)
{
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.newThread())
.subscribe(new Subscriber<String>()
{
#Override
public void onCompleted()
{
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
realm.executeTransactionAsync(new Realm.Transaction()
{
float total = 0;
float size = country.size();
String progressCount;
public void execute(Realm mRealm)
{
Countries countries = new Countries();
int i;
System.out.print("countries size: "+size);
for (i = 0; i < country.size(); i++)
{
total = (i/size * 100);
progressCount = String.format("%.0f",total);
countries.setId(country.get(i).getId());
countries.setCode(country.get(i).getCode());
countries.setName(country.get(i).getName());
countries.setContinent(country.get(i).getContinent());
countries.setKeywords(country.get(i).getKeywords());
countries.setWikipedia_link(country.get(i).getWikiLink());
mRealm.insertOrUpdate(countries);
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
//Log.d("%",progressCount);
dialog = new ProgressDialog(getActivity());
dialog.setTitle("Salvataggio country in corso");
dialog.setMessage(progressCount+"%");
}
});
}
}
},new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess()
{
Log.wtf("va","Ok");
if(dialog.isShowing())
dialog.dismiss();
}
}, new Realm.Transaction.OnError()
{
#Override
public void onError(Throwable error)
{
error.printStackTrace();
}
});
}
});
}
#Override
public void onError(Throwable e)
{
e.printStackTrace();
}
#Override
public void onNext(String s)
{
System.out.println(s);
}
});
}
but I have this error:
W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'long com.plenitudesrls.aviocalc.helpful.CountryObject.getId()' on a null object reference
In fact, I print logs and the size in onNext() is 245, in onCompleted() is null.
Why I have this error? I have another case where this works good.
Thanks
EDIT: it works good, the problem was a MalformedJson that cause the crash
I'm trying to parse image from google with android
it's work for me and for another friend of mine but it doesn't
work for some one else
When i asked him for his error he said that the Element im object was empty
and when i run my program it have 22 elements
private void setImageFromGoogle(final String name) {
new Thread(new Runnable() {
#Override
public void run() {
try {
String url = "https://www.google.co.il/search?q=" + name + "&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjpq_CYh4jRAhXXdFAKHSOBCe0Q_AUICCgB&biw=1680&bih=920";
final Document doc = Jsoup.connect(url).userAgent("Chrome").get();
runOnUiThread(new Runnable() {
#Override
public void run() {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
imageView.setImageBitmap(getImageBitmap(doc.select("[src]").get(1).attributes().get("src")));
}
});
} catch (final Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
#Override
public void run() {
runToast(e.toString());
}
});
Log.e("error", e.toString());
}
}
}).start();
}