NPE in OnPostExecute() of AsyncTask - android

I am trying to communicate with a remote device via WHTTP. I send a request and the device responds. It does not always respond immediately which is why I use AsyncTask.
Here is some trimmed down code to explain better:
private class CameraSettings extends AsyncTask<AvailableCameraSettings, Void, AvailableCameraSettings> {
private final String INNER_TAG = CameraSettings.class.getSimpleName();
AvailableCameraSettings availableCameraSettings = new AvailableCameraSettings();
#Override
protected void onPostExecute(AvailableCameraSettings availableCameraSettings) {
if(availableCameraSettings==null){
Log.e(INNER_TAG, "NULL");
return;
}
if (availableCameraSettings.getSetting().equals(SettingType.APERTURE) ) {
apertureSettings = availableCameraSettings;
ArrayAdapter<String> apertureAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item);
apertureAdapter.addAll(apertureSettings.getAvailableSettings());
apertureSpinner.setAdapter(apertureAdapter);
apertureSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemAtPosition = ((String) parent.getItemAtPosition(position));
mCameraIO.setAperture(itemAtPosition);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
apertureSpinner.setEnabled(true);
} else if (availableCameraSettings.getSetting().equals(SettingType.ISO)) {
isoSettings = availableCameraSettings;
ArrayAdapter<String> isoSpeedAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item);
isoSpeedAdapter.addAll(isoSettings.getAvailableSettings());
isoSpinner.setAdapter(isoSpeedAdapter);
isoSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemAtPosition = ((String) parent.getItemAtPosition(position));
mCameraIO.setIsoSpeed(itemAtPosition);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
isoSpinner.setEnabled(true);
}
}
#Override
protected AvailableCameraSettings doInBackground(AvailableCameraSettings... params) {
AvailableCameraSettings parameter = params[0];
if (parameter != null) {
Log.d(INNER_TAG, "***** Entered doInBackground method for setting " + parameter.getSetting().getName());
}else{
return null;
}
if (parameter.getSetting().equals(SettingType.APERTURE)) {
mCameraIO.getApertures(new CameraListener() {
#Override
public void onResult(JSONArray response) {
if (response == null) {
Log.d(INNER_TAG, " Response is Null");
return;
}
try {
Log.d(INNER_TAG, "Response is: " + response.toString(4));
extractAvailableSettings(response, apertureSettings);
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onError(CameraIO.ResponseCode responseCode, String responseMsg) {
}
});
return apertureSettings;
} else if (parameter.getSetting().equals(SettingType.ISO)) {
mCameraIO.getIsoSpeedRates(new CameraListener() {
#Override
public void onResult(JSONArray response) {
if (response == null) {
Log.d(INNER_TAG, " Response is Null");
return;
}
try {
Log.d(INNER_TAG, "Response is: " + response.toString(4));
extractAvailableSettings(response, isoSettings);
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onError(CameraIO.ResponseCode responseCode, String responseMsg) {
}
});
}
return null;
}
}
the error produced is:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference
at java.util.ArrayList.addAll(ArrayList.java:188)
at android.widget.ArrayAdapter.addAll(ArrayAdapter.java:210)
at com.thibaudperso.sonycamera.timelapse.fragments.CameraSettingsFragment$CameraSettings.onPostExecute(CameraSettingsFragment.java:311)
at com.thibaudperso.sonycamera.timelapse.fragments.CameraSettingsFragment$CameraSettings.onPostExecute(CameraSettingsFragment.java:297)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.access$500(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5468)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Line 311 is:
apertureAdapter.addAll(apertureSettings.getAvailableSettings());
I understand a null List<String> gets there, but I don't understand why doInBackground() doesn't wait until it gets the response, then return the newly populated object.

The calls to getApertures() and getIsoSpeedRates() take in a callback (CameraListener) which means it already waits for a response without needing to use an AsyncTask.
What's happening is this case is it's getting to the onResponse after doInBackground completes, because it's essentially another asynchronous task, being called from your CameraSettings AsyncTask.
I suggest removing the AsyncTask altogether, and creating similar methods to the following. Note the call to updateAdapter is called from onResult - because it's at that point you actually have the result. The onResult is essentially the same as onPostExecute of an AsyncTask, so you need to handle your functionality in there.
public void getCameraSettings(AvailableCameraSettings parameter) {
if (parameter != null) {
Log.d(INNER_TAG, "***** Entered doInBackground method for setting " + parameter.getSetting().getName());
}else{
return null;
}
if (parameter.getSetting().equals(SettingType.APERTURE)) {
mCameraIO.getApertures(new CameraListener() {
#Override
public void onResult(JSONArray response) {
if (response == null) {
Log.d(INNER_TAG, " Response is Null");
return;
}
try {
Log.d(INNER_TAG, "Response is: " + response.toString(4));
extractAvailableSettings(response, apertureSettings);
updateAdapter(SettingType.APERTURE);
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onError(CameraIO.ResponseCode responseCode, String responseMsg) {
}
});
return apertureSettings;
} else if (parameter.getSetting().equals(SettingType.ISO)) {
mCameraIO.getIsoSpeedRates(new CameraListener() {
#Override
public void onResult(JSONArray response) {
if (response == null) {
Log.d(INNER_TAG, " Response is Null");
return;
}
try {
Log.d(INNER_TAG, "Response is: " + response.toString(4));
extractAvailableSettings(response, isoSettings);
updateAdapter(SettingType.ISO);
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onError(CameraIO.ResponseCode responseCode, String responseMsg) {
}
});
}
return null;
}
Then add a method as follows. It's essentially the same as what you had in onPostExecute. It looks like isoSettings and apertureSettings were member variables so I trust you have access here, but if not, add them as a parameter to be passed to this method.
protected void updateAdapter(String settingType) {
if(availableCameraSettings==null){
Log.e(INNER_TAG, "NULL");
return;
}
if (settingType.equals(SettingType.APERTURE) ) {
apertureSettings = availableCameraSettings;
ArrayAdapter<String> apertureAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item);
apertureAdapter.addAll(apertureSettings.getAvailableSettings());
apertureSpinner.setAdapter(apertureAdapter);
apertureSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemAtPosition = ((String) parent.getItemAtPosition(position));
mCameraIO.setAperture(itemAtPosition);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
apertureSpinner.setEnabled(true);
} else if (settingType.equals(SettingType.ISO)) {
isoSettings = availableCameraSettings;
ArrayAdapter<String> isoSpeedAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item);
isoSpeedAdapter.addAll(isoSettings.getAvailableSettings());
isoSpinner.setAdapter(isoSpeedAdapter);
isoSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemAtPosition = ((String) parent.getItemAtPosition(position));
mCameraIO.setIsoSpeed(itemAtPosition);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
isoSpinner.setEnabled(true);
}
}
Note: If there's a strong reason I'm missing that you have to use an AsyncTask - you can achieve the same by simply calling your new updateAdapter method from within the onResult within the doInBackground, but I think it's unnecessary.

Related

App crashes when trying to long press after swipe refreshing

I am trying to implement the recycler-view-selection library in android, I have implemented most of it, but I am facing an issue when I am trying to refresh my screen. After refreshing my screen using SwipeRefresh, if I try to long press an item in my recycler view the app keeps crashing and I receive this error.
FATAL EXCEPTION: main
Process: com.quicklyservices.restaurants, PID: 4026
java.lang.IllegalArgumentException
at androidx.core.util.Preconditions.checkArgument(Preconditions.java:38)
at androidx.recyclerview.selection.DefaultSelectionTracker.anchorRange(DefaultSelectionTracker.java:288)
at androidx.recyclerview.selection.MotionInputHandler.selectItem(MotionInputHandler.java:60)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:164)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:97)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:770)
at android.view.GestureDetector.-wrap0(GestureDetector.java)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
This how I set my onRefreshListener
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
resetTracker();
getPendingCarts();
}
});
getPendingCarts method -
public void getPendingCarts()
{
swipeRefreshLayout.setRefreshing(true);
String token = SharedPrefUtil.getInstance().getApiToken(getActivity());
Call<ResponsePendingCart> call = ApiClient.getInstance().getPendingCarts(token);
call.enqueue(new Callback<ResponsePendingCart>() {
#Override
public void onResponse(Call<ResponsePendingCart> call, Response<ResponsePendingCart> response) {
try{
ResponsePendingCart pendingCart = response.body();
if(pendingCart.getStatus() == -1)
{
HelperClass.getInstance().forceLogout(getActivity());
}
else
{
List<Order> items = pendingCart.getItems();
if(items == null || items.size()==0)
{
container_no_order.setVisibility(View.VISIBLE);
rview_ongoing.setVisibility(View.INVISIBLE);
}
else
{
container_no_order.setVisibility(View.INVISIBLE);
rview_ongoing.setVisibility(View.VISIBLE);
AppData.shopCurrency = Html.fromHtml(pendingCart.getItems().get(0).getShop().getCurrencyHtmlCode()).toString();
for (Order item : items ) {
try{
List<ShopPromotion> promotions = item.getShopPromotion();
for (ShopPromotion promotionItem: promotions) {
List<FreeDishItem> dishItem = promotionItem.getFreeDish();
if (dishItem != null) {
for (int i = 0; i < dishItem.size() && dishItem.get(i) != null; i++) {
Dish orderItemListItem = new Dish();
orderItemListItem.setTitle(dishItem.get(i).getTitle());
orderItemListItem.setQuantity(dishItem.get(i).getQuantity());
orderItemListItem.setDetails(dishItem.get(i).getDetails());
orderItemListItem.setPrice(0.00);
orderItemListItem.setIsFreeDish(1);
item.getOrderItemList().add(orderItemListItem);
}
}
}
}
catch (Exception e) {
FirebaseCrashlytics.getInstance().log(e.toString());
}
}
if(listAdapter == null)
{
listAdapter = new OngoingListAdapter(getActivity(),items);
rview_ongoing.setAdapter(listAdapter);
rview_ongoing.setLayoutManager(new LinearLayoutManager(getActivity()));
int resId = R.anim.layout_animation_from_bottom;
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(getActivity(), resId);
rview_ongoing.setLayoutAnimation(animation);
initSelectionTracker(listAdapter,rview_ongoing);
swipeRefreshLayout.setRefreshing(false);
}
else
{
OngoingListAdapter listAdapter = new OngoingListAdapter(getActivity(),items);
rview_ongoing.setAdapter(listAdapter);
rview_ongoing.setLayoutManager(new LinearLayoutManager(getActivity()));
initSelectionTracker(listAdapter,rview_ongoing);
swipeRefreshLayout.setRefreshing(false);
}
}
}
swipeRefreshLayout.setRefreshing(false);
}
catch (Exception e)
{
container_no_order.setVisibility(View.VISIBLE);
swipeRefreshLayout.setRefreshing(false);
FirebaseCrashlytics.getInstance().log(e.toString());
}
}
#Override
public void onFailure(Call<ResponsePendingCart> call, Throwable t) {
swipeRefreshLayout.setRefreshing(false);
}
});
}
initSelectionTracker works as such -
public void initSelectionTracker(OngoingListAdapter adapter,RecyclerView recyclerView){
OngoingListItemKeyProvider keyProvider = new OngoingListItemKeyProvider(adapter);
OngoingListItemDetailsLookup itemDetailsLookup = new OngoingListItemDetailsLookup(recyclerView);
StorageStrategy<Order> storageStrategy = StorageStrategy.createParcelableStorage(Order.class);
SelectionTracker.SelectionPredicate<Order> selectionPredicate = new SelectionTracker.SelectionPredicate<Order>() {
#Override
public boolean canSetStateForKey(#NonNull Order key, boolean nextState) {
return key.getService() == 1 && tracker.getSelection().size()<2;
}
#Override
public boolean canSetStateAtPosition(int position, boolean nextState) {
return listAdapter.getItem(position).getService() == 1 && tracker.getSelection().size()<2;
}
#Override
public boolean canSelectMultiple() {
return true;
}
};
tracker = new SelectionTracker.Builder<Order>(
"my-selection-id",
recyclerView,
keyProvider,
itemDetailsLookup,
storageStrategy).withSelectionPredicate(selectionPredicate)
.build();
adapter.setTracker(tracker);
tracker.addObserver(new SelectionTracker.SelectionObserver<Order>() {
#Override
public void onSelectionChanged() {
try{
super.onSelectionChanged();
selectedItems = tracker.getSelection().size();
if(selectedItems>0){
try{
setActionBarTitle(String.format("%d Order(s) Selected",selectedItems));
Selection<Order> selections = tracker.getSelection();
for(Order selectedOrder:selections){
selectedOrders.add(selectedOrder.getTemporaryOrderId());
}
}catch (Exception e){
FirebaseCrashlytics.getInstance().log(e.toString());
}
}else{
tracker.clearSelection();
selectedOrders.clear();
setActionBarTitle("Ongoing");
}
getActivity().invalidateOptionsMenu();
}catch (Exception e){
e.printStackTrace();
}
}
});
}

Why is my ContentResolver batch operation only putting in 7 out of 21 entries?

I have three fragments in a FragmentPagerAdapter, and each of them would fetch a list of frames/data from a server using Volley. This data would later be used to update the Fragment's RecyclerView Adapter as a Cursor.
VolleyRestClientUtils.get(getString(R.string.PATH_SHOP), LOG_TAG, params, true, false, new JsonHttpResponseHandler() {
public void onSuccess(JSONObject response) {
Log.d(LOG_TAG, "request Response : " + response.toString());
try {
String status = response.getString("status");
if (RestClientUtils.STATUS_OK.equals(status)) {
final JSONArray frames = response.getJSONArray("items");
Log.d(LOG_TAG, "request Response : " + frames.length());
if (frames != null && frames.length() > 0) {
new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... voids) {
List<ContentValues> listShopFrame = ShopFrame.fromJSONArray(frames, sort);
if (listShopFrame.size() > 0 && isActivityActive()) {
ContentResolver cr = getActivity().getContentResolver();
if (!isRequestMore) {
cr.delete(ShopFrame.CONTENT_URI, ShopFrame.COLUMN_CATEGORY + "=?",
new String[]{sort});
paramSkip = frames.length();
} else {
paramSkip += frames.length();
}
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
String log = listShopFrame.size()+" ";
for (int i = 0; i < listShopFrame.size(); i++) {
operations.add(ContentProviderOperation
.newInsert(ShopFrame.CONTENT_URI)
.withValues(listShopFrame.get(i))
.build());
log += listShopFrame.get(i).toString()+"\n";
}
Log.i("loader_callback_"+sort, log);
//cr.applyBatch(ShopFrame.CONTENT_AUTHORITY, operations);
ContentValues[] opsAsArray = new ContentValues[listShopFrame.size()];
listShopFrame.toArray(opsAsArray);
cr.bulkInsert(ShopFrame.CONTENT_URI, opsAsArray);
//return true;
}
return true;
}
#Override
protected void onPostExecute(Boolean result) {
dataRefreshed = true;
Log.i("loader_callback_"+sort, "response post execute");
if (result) {
loadSucceed();
PicMixApp.getInstance().setRefreshed(ShopFrameFragment.this.getClass().getName());
} else {
loadFailed(null);
}
}
}.execute();
} else {
//TODO
//Handle error
loadFailed(getString(R.string.err_load_s, getString(R.string.frame)));
}
} else if (VolleyRestClientUtils.STATUS_RESOURCE_NOT_FOUND.equals(status)) {
hasMore = false;
loadSucceed();
} else {
loadFailed(getString(R.string.err_load_s, getString(R.string.frame)));
}
} catch (Exception e) {
Log.e(LOG_TAG, "Exception:" + e.getMessage());
loadFailed(getString(R.string.err_load_s, getString(R.string.frame)));
}
}
#Override
public void onJSONError(String responseString) {
loadFailed(getString(R.string.err_load_s, getString(R.string.frame)));
}
#Override
public void onFailure(String errMessage, int statusCode, Map<String, String> headers, byte[] responseBytes) {
loadFailed(getString(R.string.err_load_s, getString(R.string.frame)));
}
});
Whereas loadSucceed() has this following code:
if (this.recyclerView != null) {
final RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (adapter != null) {
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged() {
super.onChanged();
Log.i(DefaultRecyclerFragment.this.getClass().getName(), "onChanged");
adapter.unregisterAdapterDataObserver(this);
isLoading = false;
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
Log.i(DefaultRecyclerFragment.this.getClass().getName(), "onItemRangeRemoved:" + positionStart + ", itemcount:" + itemCount);
adapter.unregisterAdapterDataObserver(this);
isLoading = false;
}
});
if (adapter instanceof CursorRecyclerAdapter && loadMoreView != null) {
((CursorRecyclerAdapter) adapter).removeFooter(loadMoreView);
}
}
}
I've put the code to initialize the loader in the onResume() method of each fragment:
int id = 100+Integer.valueOf(sort);
Loader l = getLoaderManager().getLoader(id);
Log.i("loader_callback_"+sort, "success loading volley "+l);
if(l == null) {
getLoaderManager().restartLoader(id, null, this);
}
My problem is that there seems to be some sort of race condition happening, that the currently viewed fragment's adapter seem to be updated twice, and sometimes thrice. The initial cursor fetched by the Fragment's Loader has 10 rows, sure, but after the update, most of the time it only has 7 of the 21 rows expected to be put in.
I thought all the ContentResolvers' operations are synchronous (can only be done one after another, not simultaneously). What's going on here?
EDIT: Should I just put the loader init code in the loadSuccess() callback?
EDIT2: I should note that these Fragments extend android.support.v4.app.Fragment, and I'm using the version 27.1.1 of the Support Library.

interface between fragment and activity not working

I want pass my String json from fragment to another activity so make interface between fragment and activity but when lunch app get null exception from this line from my fragment :adapterCalljson.MethodCallbackjson(jsonStr);
this is my try so far :
interface class :
public interface AdapterCalljson {
void MethodCallbackjson(String jsonn);
}
fragment :
public class maghalat extends Fragment {
private View myFragmentView;
private RecyclerView recyclerView;
private DataAdapter adapter;
private String TAG = MainActivity.class.getSimpleName();
public ProgressDialog pDialog;
List<jsonContent> listcontent=new ArrayList<>();
public int dog=1;
public String url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
public int id;
AdapterCalljson adapterCalljson;
public String json;
public String jsonStr;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof AdapterCalljson) {
adapterCalljson = (AdapterCalljson) context;
} else {
throw new RuntimeException(context + " must implement AdapterCalljson");
}
}
#Override
public void onDetach() {
super.onDetach();
adapterCalljson = null;
}
public interface AdapterCalljson {
void MethodCallbackjson(String json);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myFragmentView = inflater.inflate(R.layout.maghalat, container, false);
adapterCalljson.MethodCallbackjson(json);
asyncRun();
return myFragmentView;
}
public void asyncRun(){
if(isNetworkConnected()) {
new GetContacts().execute();
} else
{
Toast.makeText(getActivity().getApplicationContext(), "دستگاه شما به اینترنت متصل نیست!", Toast.LENGTH_LONG).show();
}
}
public class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
id=jsonObj.getInt("pages");
JSONArray posts = jsonObj.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
JSONObject c = posts.getJSONObject(i);
jsonContent jsonContent=new jsonContent();
jsonContent.title=c.getString("title");
jsonContent.content=c.getString("content");
//img
JSONObject post_img=c.getJSONObject("thumbnail_images");
for (int j=0;j<post_img.length();j++)
{
JSONObject v=post_img.getJSONObject("mom-portfolio-two");
jsonContent.imgurl=v.getString("url");
}
jsonContent.pages=id;
jsonContent.curpage=dog;
listcontent.add(jsonContent);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pDialog.dismiss();
recyclerView=(RecyclerView)myFragmentView.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
adapter=new DataAdapter(getActivity(), listcontent, new AdapterCallback() {
#Override
public void MethodCallbackgo(String data) {
Integer s=null;
try {
s= Integer.valueOf(data);
}catch (NumberFormatException e)
{
}
if (s!=null && s>=1 && s<=id)
{
dog= Integer.parseInt(data);
url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
new GetContacts().execute();
}else
{
Toast.makeText(getActivity().getApplicationContext(),"صفحه پیدا نشد",Toast.LENGTH_SHORT).show();
}
}
#Override
public void MethodCallbacknext() {
if (dog<id)
{
dog += 1;
url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
new GetContacts().execute();
}else {
Toast.makeText(getActivity().getApplicationContext(),"این آخرین صفحه است",Toast.LENGTH_SHORT).show();
}
}
#Override
public void MethodCallbackprev() {
if (dog!=1)
{
dog-=1;
url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
new GetContacts().execute();
}else{
Toast.makeText(getActivity().getApplicationContext(),"این اولین صفحه است",Toast.LENGTH_SHORT).show();
}
}
});
recyclerView.setAdapter(adapter);
json=jsonStr;
}
}
You haven't assigned an object to adapterCalljson. Assuming you're implementing AdapterCalljson in the host activity, assign it from the context onAttach:
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof AdapterCalljson) {
adapterCalljson = (AdapterCalljson) context;
} else {
throw new RuntimeException(context + " must implement AdapterCalljson");
}
}
#Override
public void onDetach() {
super.onDetach();
adapterCalljson = null;
}
public interface AdapterCalljson {
void MethodCallbackjson(String json);
}
Firstly, your Activity containing the Fragment must implement that interface.
public class MainActivity implements AdapterCalljson {
#Override
void MethodCallbackjson(String jsonn) {
doSomethingWithJson(jsonn);
}
private void doSomethingWithJson(String json) {
}
// onCreate...
}
Next, I would recommend you create the RecyclerView outside the AsyncTask. You don't need to save the myFragmentView variable.
Additionally, you can't call the callback yet. There is no data.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.maghalat, container, false);
// recyclerView = rootView.findViewById
// adapter = ...
// recyclerView.setAdadpter...
asyncRun(); // This happens in the background. There is no JSON yet
return rootView;
}
Then, perhaps you should have doInBackground return the JSON string so you don't have to store it as a class variable.
The last argument is the return type.
public class GetContacts extends AsyncTask<Void, Void, String>
So, then it is public String doInBackground(Void params...) {} and public void onPostExecute(String result) {}.
In other words, don't just return null from doInBackground
#Override
protected String doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
jsonStr = sh.makeServiceCall(url);
// Parse JSON more...
return jsonStr;
}
And then you should be able to use your callback.
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
if (adapterCalljson != null) {
adapterCalljson.MethodCallbackjson(result);
} else {
Log.w("Callback Error", "callback not assigned");
}
// adapter.notifyDataSetChanged(); // Might want this
}

Progress dialog dismisses before the view is displayed in the gridview

I start my progress dialog in oncreate method of fragment before is initiate my web request call. In the web request call, if I fetch the response and if its success I call the notifydatasetchanged method to refresh the adapter . But the dialog gets dismissed lot before the view is updated . Please help .
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pd = ProgressDialog.show(getActivity(), "Loading...", "Please Wait...");
getProducts(highPrice, lowPrice, isLowtoHigh);
}
private void getProducts(String highPrice,String lowPrice,String isLowtoHigh) {
// loadingDialog.loading();
APIRequst.getProductsCategory(getActivity().getApplicationContext(), isLowtoHigh, lowPrice, highPrice, new APIRequestListner() {
#Override
public void onSuccess(String response) {
if (response == null || response.isEmpty()) {
Log.e("orderhistory", "success but empty");
} else {
Log.e("products", response);
try {
JSONObject mainObj = new JSONObject(response);
boolean result = mainObj.has("is_success") && mainObj.getBoolean("is_success");
String resultMessage = mainObj.getString("message");
if (resultMessage.equalsIgnoreCase("Success")) {
if (result) {
productItems.clear();
adptProductItems.clear();
JSONArray jsonOrderList = mainObj.has("categories") ? mainObj.getJSONArray("categories") : null;
if (jsonOrderList != null) {
for (int i = 0; i < jsonOrderList.length(); i++) {
JSONObject jsonObj = jsonOrderList.getJSONObject(i);
ProductListItem newItem = (new Gson()).fromJson(jsonObj.toString(), ProductListItem.class);
productItems.add(newItem);
}
adptProductItems.notifyDataSetChanged();
pd.dismiss();
}
}
} else {
if (resultMessage.equalsIgnoreCase("No Value")) {
if (pd.isShowing())
pd.dismiss();
productItems.clear();
adptProductItems.notifyDataSetChanged();
Toast.makeText(getActivity(), "Sorry no prducts to display", Toast.LENGTH_SHORT).show();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// adapter.notifyDataSetChanged();
}
#Override
public void onFailure() {
if (pd.isShowing())
pd.dismiss();
// loadingDialog.dismissDialog();
}
});
}
try to move " pd.dismiss();" below onFailure()
#Override
public void onFailure() {
if (pd.isShowing())
pd.dismiss();
// loadingDialog.dismissDialog();
}
pd.dismiss();
and
adptProductItems.notifyDataSetChanged();
//pd.dismiss(); remove fromhere
may it will help as I did in my case..

Android: how to get spinner value and check the condition

In my app i have a spinner with two items ..i have to choose the item an do action accordingly
dialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String Comment = edittext.getText().toString();
String choose = spinner.getSelectedItem()
.toString();
if (Comment != null && Comment.equalsIgnoreCase("")){
post(Comment,choose);
getActivity().finish();
}else{
showToast("Please enter you comment!");
}
}
});
dialog.show();
dialog.getWindow().setAttributes(lp);
} catch (Exception e) {
e.printStackTrace();
getActivity().finish();
}
}
private void post(String comments, String choose) throws Exception{
StringBuffer finalMessage = new StringBuffer("\nRecomends " + Data.getfName());
if(Data.getAddress() != null && !Data.getAddress().isEmpty()){
finalMessage.append("\n" + Data.getAddress());
}
-----------------> if(spinner.getSelectedItem().toString().equals("Post to personal directory & FB")){
Bundle params = new Bundle();
params.putString("message",finalMessage.toString() );
publishStory(params,comments);
}else {
try {
new FBUtils(activity).sharePlaces(attractionData, comments, null);
} catch (Exception e) {
Log.e(TAG,"sharePlaces error ",e);
}
}
}
private void publishStory(Bundle postParams,final String comments,final String choose) {
Session session = Session.getActiveSession();
if (session != null){
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
}
Request.Callback callbackRequest= new Request.Callback() {
public void onCompleted(Response response) {
if (response == null || response.equals("")
|| response.equals("false")) {
showToast("Blank response.");
} else
new fbUtils(activity).share(Data, comments, response.getError(),choose);
} catch (Exception e) {
Log.e(TAG,"sharePlaces error ",e);
}
}
};
Request request = new Request(session, Constants.fb.fbId + "/comments", postParams,
HttpMethod.POST, callbackRequest);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
the issue is the post() is not executing when clicking the dailogbutton its going into else part, i want to execute the if condition in post() method, Any help is appreciated
As you are getting the value from the spinner. The value may not be updated one .
You should use item-selected listeners.
String result="";
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
Toast.makeText(parent.getContext()), "The planet is " +
parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
// Your variable should update here
result = parent.getItemAtPosition(pos).toString();
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Now use that value in onPost method as:
private void post(String comments, String choose) throws Exception{
StringBuffer finalMessage = new StringBuffer("\nRecomends " + Data.getfName());
if(Data.getAddress() != null && !Data.getAddress().isEmpty()){
finalMessage.append("\n" + Data.getAddress());
}
Log.v("TEST",spinner.getSelectedItem().toString());
-----------------> if(result.equals("Post to personal directory & FB")){
Bundle params = new Bundle();
params.putString("message",finalMessage.toString() );
publishStory(params,comments);
}else {
try {
new FBUtils(activity).sharePlaces(attractionData, comments, null);
} catch (Exception e) {
Log.e(TAG,"sharePlaces error ",e);
}
}
}
Try like this:
private Spinner status;
status = (Spinner) findViewById(R.id.status);
final ArrayList<Simplestatus> statusList = new ArrayList<Simplestatus>();
Simplestatus tempstatus = new Simplestatus();
tempstatus.setSimpleStatusName("ZERO");
tempstatus.setSimpleStatusValue("0");
Simplestatus tempstatus1 = new Simplestatus();
tempstatus1.setSimpleStatusName("ONE");
tempstatus1.setSimpleStatusValue("1");
statusList.add(tempstatus);
statusList.add(tempstatus1);
SpinnerAdapter stateAdaptor = new SpinnerAdapter(SettingActivity.this,statusList);
// stateList.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
status.setAdapter(stateAdaptor);
status.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,int position, long arg3) {
changeStatus(statusList.get(position));
selected = statusList.get(position).getsimpleStatusName();
System.out.println("selected"+selected);
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
public class Simplestatus
{
private String simpleStatusName;
private String simpleStatusValue;
public String getSimpleStatusName()
{
return simpleStatusName;
}
public void setSimpleStatusName(String simpleStatusName)
{
this.simpleStatusName = simpleStatusName;
}
public String getsimpleStatusValue()
{
return simpleStatusValue;
}
public void setsimpleStatusValue(String simpleStatusValue)
{
this.simpleStatusValue = simpleStatusValue;
}
}

Categories

Resources