Stuck on Android.os.Bundle with Null Object Reference - java

I don't know why this error happens. I have checked all the code that link to this one but still doesn't give any solution.
The IDE just gimme error like this :
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Bundle.getInt(java.lang.String)' on a null object reference
at com.gook.rebill.fragment.HomeFragment.onAttach(HomeFragment.java:74)
I know it's a null object reference, but still i don't get where the cause of error.
Please help me.
this is my code :
public class HomeFragment extends Fragment implements InternetConnectionListener, ApiHandler.ApiHandlerListener {
private static final String ARG_SECTION_NUMBER = "section_number";
private final int CATEGORY_ACTION = 1;
private CategorySelectionCallbacks mCallbacks;
private ArrayList<Category> categoryList;
private ListView categoryListView;
private String Error = null;
private InternetConnectionListener internetConnectionListener;
public HomeFragment() {
}
public static HomeFragment newInstance(int sectionNumber) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((HomeActivity) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
try {
mCallbacks = (CategorySelectionCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement CategorySelectionCallbacks.");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
categoryListView = (ListView) rootView.findViewById(R.id.categoryListView);
return rootView;
}
#Override
public void onResume() {
super.onResume();
if (UtilMethods.isConnectedToInternet(getActivity())) {
initCategoryList();
} else {
internetConnectionListener = (InternetConnectionListener) HomeFragment.this;
showNoInternetDialog(getActivity(), internetConnectionListener,
getResources().getString(R.string.no_internet),
getResources().getString(R.string.no_internet_text),
getResources().getString(R.string.retry_string),
getResources().getString(R.string.exit_string), CATEGORY_ACTION);
}
}
public class getCategList extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
/**
* json is populating from text file. To make api call use ApiHandler class
*
* <CODE>ApiHandler apiHandler = new ApiHandler(this, URL_GET_CATEGORY);</CODE> <BR>
* <CODE>apiHandler.doApiRequest(ApiHandler.REQUEST_GET);</CODE> <BR>
*
* You will get the response in onSuccessResponse(String tag, String jsonString) method
* if successful api call has done. Do the parsing as the following.
*/
URL hp = null;
try {
hp = new URL(
getString(R.string.liveurl) + "foodcategory.php");
Log.d("URL", "" + hp);
URLConnection hpCon = hp.openConnection();
hpCon.connect();
InputStream input = hpCon.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(input));
String x = "";
x = r.readLine();
String total = "";
while (x != null) {
total += x;
x = r.readLine();
}
Log.d("UR1L", "" + total);
JSONArray j = new JSONArray(total);
Log.d("URL1", "" + j.length());
categoryList = new ArrayList<Category>();
for (int i = 0; i < j.length(); i++) {
Category category = new Category();// buat variabel category
JSONObject Obj;
Obj = j.getJSONObject(i); //sama sperti yang lama, cman ini lebih mempersingkat karena getJSONObject cm d tulis sekali aja disini
category.setId(Obj.getString(JF_ID));
category.setTitle(Obj.getString(JF_TITLE));
category.setIconUrl(Obj.getString(JF_ICON));
if (!TextUtils.isEmpty(Obj.getString(JF_BACKGROUND_IMAGE))) {
category.setImageUrl(Obj.getString(JF_BACKGROUND_IMAGE));
}
Log.d("URL1",""+Obj.getString(JF_TITLE));
categoryList.add(category);
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
categoryListView.setAdapter(new CategoryAdapter(getActivity(), mCallbacks, categoryList));
}
});
}catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (JSONException e) {
// TODO Auto-generated catch block
Error = e.getMessage();
e.printStackTrace();
} catch (NullPointerException e) {
// TODO: handle exception
Error = e.getMessage();
}
return null;
}
}
//! function for populate category list
private void initCategoryList() {
new getCategList().execute();
}
#Override
public void onConnectionEstablished(int code) {
if (code == CATEGORY_ACTION) {
initCategoryList();
}
}
#Override
public void onUserCanceled(int code) {
if (code == CATEGORY_ACTION) {
getActivity().finish();
}
}
//! catch json response from here
#Override
public void onSuccessResponse(String tag, String jsonString) {
//! do same parsing as done in initCategoryList()
}
//! detect response error here
#Override
public void onFailureResponse(String tag) {
}
//! callback interface listen by HomeActivity to detect user click on category
public static interface CategorySelectionCallbacks {
void onCategorySelected(String catID, String title);
}
}
Here where I use the fragment code, in HomeActivity:
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}

I think getArguments() return null.
You can see these example:
Android Fragment getArguments() returns null
Fragment getArguments() returns null

From the code that you have attached, it appears to happen here.
hp = new URL(
getString(R.string.liveurl) + "foodcategory.php");
Question is - what is R. Can R be null while you are trying to access string.liveurl? This seems to be the likely problem. Can you use debugger to check what is R?

Try this -
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (CategorySelectionCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement CategorySelectionCallbacks.");
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
((HomeActivity) getActivity()).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
}

You should do in this way:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (CategorySelectionCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement CategorySelectionCallbacks.");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
categoryListView = (ListView) rootView.findViewById(R.id.categoryListView);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((HomeActivity) getActivity()).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
}
Edit 1:
You should replace HomeFragment by this way:
HomeFragment homeFragment = HomeFragment.newInstance(my_int);
_viewPagerAdapter.addFragments(homeFragment,"Home");
Reason: Simply you were creating instance of Fragment by default constructor instead of instance with Arguments.
Hope this would help you.

Related

List view in fragment with Async Task

my error log
I tried to load list view in my fragment.But my app crashes on clicking the button to populate my listview. I don't know what error i did.Any help will be appreciated.I have tried most of the stuffs regarding this..But nothing works well.(i have removed some codes to avoid clumsy look)
Here is my Fragment code :
public class Func extends Fragment {
ArrayList<Flowers> flowersList = new ArrayList<Flowers>();
String url ="http://113.193.30.155/MobileService/MobileService.asmx/GetSampleData";
#Override
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab2, container, false);
FlowerAdapter adapter=new FlowerAdapter(getActivity().getApplicationContext(),R.layout.flower_list_xml,flowersList);
ListView listView=(ListView)rootView.findViewById(R.id.listView);
listView.setAdapter(adapter);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
Button b = (Button)getView().findViewById(R.id.button);
b.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
new BackTask().execute(url);
}
});
}
// My Async task starts here
public class BackTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
String result = null;
BufferedReader reader = null;
try {
URL url = new URL(strings[0]);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
Log.d("testhtt2", "test");
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
Log.d("test44", sb.toString());
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return result;
}
}
#Override
protected void onPostExecute(String s){
try {
JSONArray ar =new JSONArray(s);
for (int i = 0; i < ar.length(); i++){
JSONObject jsonObject=ar.getJSONObject(i);
Flowers flowers= new Flowers();
flowers.setName(jsonObject.getString("NAME"));
flowersList.add(flowers);
}
} catch (JSONException e) {
e.printStackTrace();
}
You return null in your doInBackground, which you then attempt to parse as a JSONArray in your OnPostExecute. Return a proper String from your doInBackground method, and see if that helps.
Do a null check before using getView() like
if(getView()!=null){
//Your code
}
Also it is better to initialize the button in oncreate view using the rootview intead of getview()
EDIT:
Your network call which your are doing has to be moved to doInBackground as it should be done in background thread and fetch the result.The fetched result should be added to the list in onPostExecute.Hope this helps you
public class SampleClass extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
BufferedReader reader = null;
String result=null;
try {
URL url = new URL(strings[0]);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
Log.d("testhtt2", "test");
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
Log.d("test44", sb.toString());
result= sb.toString();
} catch (Exception e) {
e.printStackTrace();
result= null;
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
result= null;
}
}
return result;
}
}
#Override
protected void onPostExecute(String s){
try {
JSONArray ar =new JSONArray(s);
for (int i = 0; i < ar.length(); i++){
JSONObject jsonObject=ar.getJSONObject(i);
Flowers flowers= new Flowers();
flowers.setName(jsonObject.getString("NAME"));
flowersList.add(flowers);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
you can try with view insteadof getView() in onViewCreated() method.
public class ListView extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab2, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button b = (Button) view.findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new BackTask().execute("http://113.193.30.155/MobileService/MobileService.asmx/GetSampleData");
}
});
}
private class BackTask extends AsyncTask<String, Void, String> {
String result;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
result = Utility.executeHttpGet(params[0]);
} catch (Exception e) {
Log.e("ListView", e.getMessage(), e);
}
return result;
}
#Override
protected void onPostExecute(String s) {
try {
JSONArray ar = new JSONArray(s);
for (int i = 0; i < ar.length(); i++) {
JSONObject jsonObject = ar.getJSONObject(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Try this code
public class Listview extends Fragment {
ArrayList<Flowers> flowersList = new ArrayList<Flowers>();
String url ="http://113.193.30.155/MobileService/MobileService.asmx/GetSampleData";
ListView listview;
View rootView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (rootView!= null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
rootView = inflater.inflate(R.layout.tab2, container, false);
} catch (InflateException ignored) {
}
listView=(ListView)rootView.findViewById(R.id.listView);
Button b = (Button)rootView.findViewById(R.id.button);
b.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
new BackTask().execute(url);
}
});
return view;
}
private class BackTask extends AsyncTask<String,String,String>{
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
return null;
}
#Override
protected void onPostExecute(String s){
try {
JSONArray ar =new JSONArray(s);
for (int i = 0; i < ar.length(); i++){
JSONObject jsonObject=ar.getJSONObject(i);
Flowers flowers= new Flowers();
flowers.setName(jsonObject.getString("NAME"));
flowersList.add(flowers);
}
FlowerAdapter adapter=new FlowerAdapter(getActivity(),R.layout.flower_list_xml,flowersList);
listView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}

Swipe Refresh freezes when executing async task

I'm encountering a problem, when I try running an asynchronous task on refresh using a swipe refresh layout it "freezes" and doesn't rotate. When the task is done it just disappears.
Here is my code:
HotActivityFragment.java:
public class HotActivityFragment extends Fragment {
ListView hotList;
SwipeRefreshLayout mSwipeRefreshLayout;
Context context;
SharedPreferences sharedPreferences;
HotListAdapter hotListAdapter;
public HotActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hot, container, false);
context = getContext();
mSwipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.activity_main_swipe_refresh_layout);
hotList = (ListView)view.findViewById(R.id.hotListView);
hotList.setOnScrollListener(new EndlessScrollListener(getActivity()));
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
try {
ArrayList<ListTypeItem> initial_list = new DownloadPosts(getActivity()).execute().get();
this.hotListAdapter = new HotListAdapter(getContext(), initial_list);
hotList.setAdapter(hotListAdapter);
}catch(Exception e)
{
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrievePosts();
}
});
mSwipeRefreshLayout.setColorSchemeResources(R.color.accentColor, R.color.backgroundColor);
return view;
}
public void retrievePosts()
{
// showing refresh animation before making http call
mSwipeRefreshLayout.setRefreshing(true);
//shared preferences = empty
sharedPreferences.edit().putString("last_time_downloaded", "empty").commit();
try {
ArrayList<ListTypeItem> listItems = new DownloadPosts(getActivity(), mSwipeRefreshLayout).execute().get();
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
} catch (Exception e) {
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setRefreshing(false);
//for testing purposes
// new Handler().postDelayed(new Runnable() {
// #Override public void run() {
// mSwipeRefreshLayout.setRefreshing(false);
// }
// }, 5000);
}
}
DownloadPosts.java:
public class DownloadPosts extends AsyncTask<Void, Void, ArrayList<ListTypeItem>> {
SharedPreferences sharedPreferences;
SwipeRefreshLayout swipeRefreshLayout;
public DownloadPosts(Activity activity)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
}
public DownloadPosts(Activity activity, SwipeRefreshLayout swipeRefreshLayout)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
this.swipeRefreshLayout = swipeRefreshLayout;
}
#Override
protected ArrayList<ListTypeItem> doInBackground(Void... args)
{
StringBuilder parsedString = new StringBuilder();
ArrayList<ListTypeItem> downloadList = new ArrayList<>();
StringBuilder str = new StringBuilder();
if(sharedPreferences.getBoolean("Thomas More",false))
{
str.append("190155257998823,");
}
String school_url = str.toString();
if(school_url.length() > 0)
{
school_url = school_url.substring(0, str.length()-1);
}
try{
String date = "";
//checken of opnieuw moet bepaald worden
// + in de adapter moet als gereload wordt last_time_downloaded == empty
if(!sharedPreferences.getString("last_time_downloaded","empty").equals("empty"))
{
String last_date = sharedPreferences.getString("last_time_downloaded","nothing");
last_date = last_date.replace(" ","T");
date= "&datum_last_posted=" + last_date;
}
URL url = new URL("http://localhost/getpostlist.php?school_post=" + school_url + date);
URLConnection conn = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String json;
while((json = bufferedReader.readLine())!= null)
{
parsedString.append(json + "/n");
}
String s = parsedString.toString().trim();
//converten van string opgehaald via http naar jsonobject
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++)
{
JSONObject tempObj = array.getJSONObject(i);
School_WithoutImage tempSchool = new School_WithoutImage(tempObj.getString("school_id"),
tempObj.getString("post_message"),tempObj.getInt("views"),tempObj.getInt("likes")
,tempObj.getInt("post_id"),tempObj.getString("datum_posted"));
downloadList.add(tempSchool);
if(i == array.length()-1) {
sharedPreferences.edit().putString("last_time_downloaded",tempObj.getString("datum_posted")).commit();
}
}
JSONObject obj = array.getJSONObject(0);
}catch(Exception e)
{
Log.d("Exception", e.toString());
}
return downloadList;
}
#Override
protected void onPostExecute(ArrayList<ListTypeItem> result)
{
if(this.swipeRefreshLayout != null)
{
// swipeRefreshLayout.setRefreshing(false);
}
}
}
I have no idea why the swiperefreshview doesn't spin. Anyone has an idea?
Because the call to get():
.execute().get()
Forces the UI thread to wait for the AsyncTask to finish.
Instead you should look at doing this in the onPostExecute method:
protected void onPostExecute(ArrayList<ListTypeItem> listItems) {
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
}
Because you are waiting for the result from asynctask by calling get just after execute. And further passing it to list.
You can use Local Broadcast Listener or can create an interface and can us that as callback, without freezing UI

How to Cast Fragment's context to interface

I want to use return a value from AsyncTask class by using interface. Problem is that my following code is work fine in Activity but not in fragment class.
I got ClassCastException like this:
java.lang.ClassCastException: com.demo.HomeActivity cannot be cast to com.demo.helper.OnTaskCompleteListener
at com.demo.util.JSONParseAsync.<init>(JSONParseAsync.java:33)
at com.demo.fragment.PersonalDetailFragment.loadProfileAction(PersonalDetailFragment.java:93)
at com.demo.fragment.PersonalDetailFragment.onCreate(PersonalDetailFragment.java:81)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1942)
Interface class:
public interface OnTaskCompleteListener {
void onTaskComplete(JSONObject jsonObject);
}
PersonalDetailFragment class:
public class PersonalDetailFragment extends Fragment implements OnTaskCompleteListener {
private View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_personal_detail, container,
false);
loadProfileAction();
return view;
}
private void loadProfileAction() {
SessionPreference preference = new SessionPreference(getActivity());
try {
String encodedUrl = URLEncoder.encode(preference.getSessionId(), "UTF-8")
+ ","
+ URLEncoder.encode(Constants.URL_TOKEN, "UTF-8");
// URL base64Encode
String processUrl = Base64.encodeToString(encodedUrl.getBytes("UTF-8"), Base64.DEFAULT);
JSONParseAsync parseAsync = new JSONParseAsync(getContext()); // also try getActivity()
parseAsync.execute((URLConstants.GET_USER_DETAIL_URL+processUrl).trim());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onTaskComplete(JSONObject jsonObject) {
try {
boolean status = jsonObject.getBoolean(URLConstants.TAG_STATUS);
Log.e(Constants.DEBUG_TAG, "Status:- " + status);
if (status == true) {
JSONArray dataarray = jsonObject.getJSONArray(URLConstants.TAG_DATA);
JSONObject data = dataarray.getJSONObject(0);
fillProfileData(data);
} else if (status == false) {
Snackbar.make(view,
"Incorrect User Name OR Password",
Snackbar.LENGTH_LONG).show();
}
Log.i("GARG", "Excution Line Finish ");
} catch (Exception e) {
e.printStackTrace();
}
}
JSONParseAsync class:
public class JSONParseAsync extends AsyncTask<String, String, JSONObject>{
private Context mContext;
ProgressDialog mProgress;
private OnTaskCompleteListener mCallback;
public JSONParseAsync(Context context){
this.mContext = (AppCompatActivity)context;
this.mCallback = (OnTaskCompleteListener) mContext;
}
#Override
protected JSONObject doInBackground(String... URL) {
JSONObject jsonObj = null;
try{
Log.d(Constants.DEBUG_TAG, "line excucation 2 doInBackground");
ServiceHandler sh = new ServiceHandler();
String url = URL[0];
Log.d(Constants.ACTIVITY_TAG, "...." + url);
// Making a request to url and getting response.
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d(Constants.JSON_TAG, "" + jsonStr);
if (jsonStr != null) {
jsonObj = new JSONObject(jsonStr);
Log.e(Constants.JSON_TAG, "" + jsonObj);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObj;
}
#Override
protected void onPreExecute() {
Log.d(Constants.DEBUG_TAG, "line excucation 1 onPreexcute");
mProgress = new ProgressDialog(mContext);
mProgress.setMessage("Downloading nPlease wait...");
mProgress.show();
}
#Override
protected void onProgressUpdate(String... values) {
Log.d(Constants.DEBUG_TAG, "line excucation 3 onProgressUpdate");
mProgress.setMessage(values[0]);
}
#Override
protected void onPostExecute(JSONObject result) {
Log.d(Constants.DEBUG_TAG, "line excucation 3 onPostExecute");
mProgress.dismiss();
//This is where you return data back to caller
Log.d(Constants.APP_TAG, " final result:- "+result);
mCallback.onTaskComplete(result);
}
}
Please help me:
By doing this
JSONParseAsync parseAsync = new JSONParseAsync(getContext());
you're sending the Activity to your AsyncTask, but it is your Fragment that implements OnTaskCompleteListener.
Either have your Activity implement your interface, or
do this :
JSONParseAsync parseAsync = new JSONParseAsync(this, getContext());
and change your AsyncTask constructor to
public JSONParseAsync(OnTaskCompleteListener listener, Context context){
this.mContext = context;
//this.mContext = (AppCompatActivity)context; -> you don't need that cast, AppCompatActivity is a subclass of Context
this.mCallback = listener;
}
Use 2 Parameters for your Tasks Constructor:
public JSONParseAsync(Context context, OnTaskCompleteListener listener){
this.mContext = context;
this.mCallback = listener;
}
and create a new instance by using
JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this);
Because when you pass the Context, you don't pass the fragment but the underlying activity. So you'll probaly need 2 parameters if you want to use your task inside your fragment.
You problem is, because you have passed the Activity context to JSONParseAsync and inside its constructor you are casting it to activity AppCompatActivity following the activity casting to your OnTaskCompleteListener.. So, your activity should be implementing the listener and not your fragment.
just let HomeActivity implement your interface OnTaskCompleteListener.
Example:
public class HomeActivity extends AppCompatActivity implements OnTaskCompleteListener{
...
}
In my opinion, don't create your custom classes unless and until its required. In your case you should have achieved your task with anonymous class too.. there's no need to create separate class..
I hope you got my point.
Still, what you can do is, pass the context and OnTaskCompleteListener in the constructor
private void loadProfileAction() {
...
JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this); // also try getActivity()
...
}
and change the constructor to:
public JSONParseAsync(Context context, OnTaskCompleteListener listener){
this.mContext = context;
this.mCallback = listener;
}

Why is there too much work on main thread?

So I'm trying to make a simple application that makes stores group events in a MySQL database then retrieves them for people to join. In this fragment I list all the events by using a JSONParser class to query the database. I use an Async class to do the querying. The fragment will initially query the db on startup or whenever the user decides to limit the scope of the events by selecting something in a spinner or when the user pushes a refresh button. I have been getting messages like
Choreographer﹕ Skipped 95 frames! The application may be doing too much work on its main thread.
while running the program and I'm not sure why. I think it might be because I call the Async class too much, but I'm not sure.
public class mainActivityFragment extends Fragment {
final public String information = "information";
public Spinner specifySubject;
private ArrayList<String> list = new ArrayList<>();
private ArrayList<EventObject> eventList = new ArrayList<>();
JSONParser jsonParser = new JSONParser();
ListView test;
ArrayAdapter adapter;
// url to create new product
private static String url_get_event = "";
private ProgressDialog pDialog;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, list);
test = (ListView) v.findViewById(R.id.listView);
new CreateNewProduct().execute();
if(pDialog.isShowing()){
pDialog.dismiss();
}
test.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
Intent in = new Intent(getActivity(), AttendInformation.class);
EventObject clickedEvent = eventList.get(position);
String[] testInformation = {clickedEvent.getTo().toString(), clickedEvent.getLocation(), clickedEvent.getTitle(), clickedEvent.getDurationString(), clickedEvent.getDescription(), clickedEvent.getSubject()};
in.putExtra(information, testInformation);
startActivity(in);
}
});
Button createEventButton = (Button) v.findViewById(R.id.Button2);
createEventButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent in = new Intent(getActivity(), createEvent.class);
startActivity(in);
}
});
specifySubject = (Spinner) v.findViewById(R.id.spinner);
specifySubject.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
AsyncTask task;
task = new CreateNewProduct().execute();
try {
task.get(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
if (position == 0) {
} else {
String selectedSubj = getResources().getStringArray(R.array.class_array)[position];
for (int i = 0; i < eventList.size(); i++) {
if (!eventList.get(i).getSubject().equals(selectedSubj)) {
list.remove(list.indexOf(eventList.get(i).getTitle()));
eventList.remove(i);
i--;
}
}
adapter.notifyDataSetChanged();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Button refresh = (Button) v.findViewById(R.id.leftButton);
refresh.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AsyncTask task;
task = new CreateNewProduct().execute();
try {
task.get(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
if (specifySubject.getSelectedItemPosition() == 0) {
} else {
String selectedSubj = getResources().getStringArray(R.array.class_array)[specifySubject.getSelectedItemPosition()];
for (int i = 0; i < eventList.size(); i++) {
if (!eventList.get(i).getSubject().equals(selectedSubj)) {
list.remove(list.indexOf(eventList.get(i).getTitle()));
eventList.remove(i);
i--;
}
}
adapter.notifyDataSetChanged();
}
}
});
return v;
}
class CreateNewProduct extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Getting Events...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
JSONArray jsonArr = jsonParser.getJSONFromUrl(url_get_event);
for(int n = 0; n < jsonArr.length(); n++)
{
try {
JSONObject object = jsonArr.getJSONObject(n);
if(!list.contains(object.getString("title"))){
String[] time = object.getString("time").split(":");
time[1] = time[1].substring(0, 2);
EventObject tempEven = new EventObject(object.getString("title"), object.getString("location"), object.getString("description"), object.getString("subject"), 0, new TimeObject(Integer.parseInt(time[0]), Integer.parseInt(time[1])));
eventList.add(tempEven);
list.add(object.getString("title"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
test.setAdapter(adapter);
pDialog.dismiss();
}
}
}

Gridview is refreshed from start when scrollbar reaches end

This happens while loading data in gridview. This is my fragment containing scroll listener over gridview. But whenever i reload the data then whole gridview reload and scroll starts from top not from where the data is loaded. I am using single gridview.
public class Women_Ethnic_Fragment extends Fragment {
private static String url = "http://------/-------";
private int mVisibleThreshold = 5;
private int mCurrentPage = 0;
private int mPreviousTotal = 0;
private boolean mLoading = true;
private boolean mLastPage = false;
public Women_Ethnic_Fragment() {
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.gridview_fragment, container,
false);
setRetainInstance(true);
arrayList = new ArrayList<Items>();
gridView = (GridView) rootView.findViewById(R.id.gridView1);
new LoadData().execute(url);
//scrolling portion
gridView.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (mLoading) {
if (totalItemCount > mPreviousTotal) {
mLoading = false;
mPreviousTotal = totalItemCount;
mCurrentPage++;
if (mCurrentPage + 1 > 50) {
mLastPage = true;
}
}
}
if (!mLastPage
&& !mLoading
&& (totalItemCount - visibleItemCount) <= (firstVisibleItem + mVisibleThreshold)) {
//new asynctask called
new LoadData()
.execute("http://-------/---------");
mLoading = true;
}
}
#Override
public void onScrollStateChanged(AbsListView view,
int scrollState) {
}
});
return rootView;
}
//my asynctask
private class LoadData extends AsyncTask<String,
Void, Void> {
#Override
protected void onPostExecute(Void result) {
tp.dismiss();
adap = new Grid_View_Adatper(getActivity().getApplicationContext(),
arrayList);
gridView.setAdapter(adap);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
tp = new TransparentProgressDialog(getActivity(),
R.drawable.spinner);
tp.setCancelable(false);
tp.setCanceledOnTouchOutside(false);
tp.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(String... urls) {
try {
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(urls[0]);
HttpResponse response = client.execute(httpget);
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONArray json = new JSONArray(data);
for (int i = 0; i < json.length(); i++) {
JSONObject e = json.getJSONObject(i);
String name = e.getString("name");
String price = e.getString("price");
String image = e.getString("image");
String code = e.getString("sku");
tems = new Items(name, price, image, code);
arrayList.add(tems);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
} catch (IOException e) {
} catch (RuntimeException e) {
}
return null;
}
}
Please help someone.
Thanks in advane.
The problem is you instantiate adapter over and over again. Instead check your adapter first, if it is not null, then set your data, then notify dataset changes.
if (adapter == null) {
adapter = new GridViewAdapter...
gridView.setAdapter(adapter)
}
// list refers the list inside in your adapter
list.addAll(newList); // or do your implementation
adapter.notifyDataSetChanged();

Categories