crg
crg

Reputation: 4577

Call non-static method in Static method JAVA

EDITED:

The real purpose of that is to have one activity and on class who fetch data and render it to the activity.

The problem is I have dropdown menu. When I clicked on an item of the menu it change my url but it does not load or fetch my data to the activity but when i clicked again it works but with the paramaters selected just before and if I clicked again it still works but still with the previous elements selected.

My "teacher" said I have to call build into my callback method. But it doesen't work at all. And I still didn't find any solution :/.

As you recommended I changed everything for non-static method

I thought why not saving an history of the dropdown, compare the current value with the saved value and if it's diffrent it means it was changed so reload the app to make new fetch and displyed new data.

But I got :

Here my all code

PhotosActivity

public class PhotosActivity extends AppCompatActivity {

    // Local variable
    private OkHttpClient httpClient;
    private ImageButton home_btn;
    private ImageButton favorites_btn;
    private ImageButton search_btn;
    private ImageButton profil_btn;
    // Constante variable
    private static final String TAG = "PhotoActivity";
    private static final String clientId = "bb0c749c6403fd2";

    // Private shared variable
    private static  List<Photo> mPhotos;
    private static JSONArray mItems;
    private static String mAccessToken;
    private static String userID;
    static Activity activity;

    // Shared variable
    private static String selectedItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photos);
        this.home_btn = findViewById(R.id.home_button);
        this.favorites_btn = findViewById(R.id.favorites_button);
        this.search_btn = findViewById(R.id.search_button);
        this.profil_btn = findViewById(R.id.profil_button);

        final HttpHandler httpHandler = new HttpHandler();
        httpHandler.fetchData();
        build();

        activity = this;

        Spinner spinner=(Spinner)findViewById(R.id.spinner);
        String[] filters=getResources().getStringArray(R.array.filters);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,R.layout.spinner,R.id.text, filters);
        spinner.setAdapter(adapter);


        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
            {
                selectedItem = parent.getItemAtPosition(position).toString();
//                httpHandler.fetchData();
//                build();
            }
            public void onNothingSelected(AdapterView<?> parent)
            {
                Log.d("TAG", "Error");
            }
        });

        home_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent next_activity = new Intent(getApplicationContext(), PhotosActivity.class);
                finish();
                startActivity(next_activity);
            }
        });
        favorites_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent next_activity = new Intent(getApplicationContext(), FavoriteActivity.class);
                finish();

                startActivity(next_activity);
            }
        });
        search_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent next_activity = new Intent(getApplicationContext(), SearchActivity.class);
                finish();
                startActivity(next_activity);
            }
        });
        profil_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent next_activity = new Intent(getApplicationContext(), ProfileActivity.class);
                finish();
                startActivity(next_activity);
            }
        });
    }

    public void Filters() {
        String hSection;
        String hSort;
        String hShowV;

        hSection = HttpHandler.section ;
        hSort = HttpHandler.sort;
        hShowV = HttpHandler.showV;
        Intent next_activity = new Intent(getApplicationContext(), FavoriteActivity.class);

        if(selectedItem != null) {
            if (selectedItem.equals("Most Viral")) {
                HttpHandler.sort = "viral/";
                HttpHandler.section = "hot/";
                if ( (!HttpHandler.sort.equals(hSort))  || (!HttpHandler.section.equals(hSection))) {
                    Log.d("TAG", "most: "+HttpHandler.section);
                    Log.d("TAG", "H most: "+hSection);
//                    activity.recreate();
//                    onRestart();
                    finish();
                    startActivity(next_activity);
                }
            } else if (selectedItem.equals("Newest")) {
                HttpHandler.section = "top/";
                HttpHandler.sort = "time/";
                if ( (!HttpHandler.sort.equals(hSort))  || (!HttpHandler.section.equals(hSection))) {
                    Log.d("TAG", "new: "+HttpHandler.section);
                    Log.d("TAG", "H new: "+hSection);
                    finish();
                    startActivity(next_activity);
//                    activity.recreate();
//                    onRestart();
                }
            } else if (selectedItem.equals("Rising")) {
                HttpHandler.section = "user/";
                HttpHandler.sort = "rising/";
                HttpHandler.showV = "?showViral=false";
                if ( (!HttpHandler.sort.equals(hSort))  || (!HttpHandler.section.equals(hSection))) {
                    Log.d("TAG", "rising: "+HttpHandler.section);
                    Log.d("TAG", "H rising: "+hSection);
//                    onRestart();
//                    activity.recreate();
                    finish();
                    startActivity(next_activity);
                }
            } else {
                Log.d(TAG, "Might be a problem");
            }
        } else {
                activity.recreate();
        }
    }
    public void build () {
        try {
            for(int i = 0; i < mItems.length(); i++) {
                JSONObject item = mItems.getJSONObject(i);
                Photo photo = new Photo();
                if(item.getBoolean("is_album")) {
                    photo.id = item.getString("cover");
                } else {
                    photo.id = item.getString("id");
                }
                photo.title = item.getString("title");
                mPhotos.add(photo);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        render(mPhotos);
                    }
                });
            }

        } catch (Exception e) {
            Log.e("JSONerr" , "Something went wrong.");
        }
    }

    private static class PhotoVH extends RecyclerView.ViewHolder {
        ImageView photo;
        TextView title;

        public PhotoVH(View itemView) {
            super(itemView);
        }
    }

    private void render(final List<Photo> photos) {
        RecyclerView rv = (RecyclerView)findViewById(R.id.rv_of_photos);
        rv.setLayoutManager(new LinearLayoutManager(this));

        RecyclerView.Adapter<PhotoVH> adapter = new RecyclerView.Adapter<PhotoVH>() {
            @NonNull
            @Override
            public PhotoVH onCreateViewHolder(ViewGroup parent, int viewType) {
                PhotoVH vh = new PhotoVH(getLayoutInflater().inflate(R.layout.item, null));
                vh.photo = (ImageView) vh.itemView.findViewById(R.id.photo);
                vh.title = (TextView) vh.itemView.findViewById(R.id.title);
                return vh;
            }

            @Override
            public void onBindViewHolder(PhotoVH holder, int position) {
                Picasso.with(PhotosActivity.this).load("https://i.imgur.com/" +
                        photos.get(position).id + ".jpg").into(holder.photo);
                holder.title.setText(photos.get(position).title);
            }

            @Override
            public int getItemCount() {
                return photos.size();
            }
        };

        rv.setAdapter(adapter);
    }

    public static void getUserID(String UserID) {
        Log.d("TAG", UserID);
        userID = UserID;
    }

    public void callBackPhoto( List<Photo> photos, JSONArray items)
    {
         mPhotos = photos;
         mItems = items;
//         build();
    }

}

HttpHandler

public class HttpHandler {
    private static final String TAG = "HttpHandler";
    private static String clientId = "bb0c749c6403fd2";
    private static OkHttpClient httpClient;
    private static String mAccessToken;

    // URL BUILDER VARIABLES
    public static String section = "hot/";
    public static String sort = "viral/";
    public static String page;
    public static String showV;
    public static String mUrl;

    public void fetchData() {
        httpClient = new OkHttpClient.Builder().build();
        photosActivity.Filters();
        mUrl = "https://api.imgur.com/3/gallery/" + section + sort;
//        Log.d("TAG", "Sort: " + sort + ": URl is" + mUrl);
        Request request = new Request.Builder()
                .url(mUrl + "0.json" + showV)
                .addHeader("Authorization", "Client-ID " + clientId)
                .header("User-Agent", "epicture")
                .build();
        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "An error has occurred " + e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    JSONObject data = new JSONObject(response.body().string());
                    JSONArray items = data.getJSONArray("data");
                    final List<Photo> photos = new ArrayList<Photo>();
                    photosActivity.callBackPhoto(photos, items);
                } catch (Exception e) {
                    Log.e("JSONerr", "Something went wrong.");
                }
            }
        });
    }

    public static void getLoginData(String accessToken) {
        mAccessToken = accessToken;
    }
}

Upvotes: 0

Views: 2970

Answers (3)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79580

It doesn't look like making sense to declare callBackPhoto as a static method. If you have put static keyword accidentally in its declaration, simply remove it to solve your problem i.e. replace

public static void callBackPhoto( List<Photo> photos, JSONArray items)

with

public void callBackPhoto( List<Photo> photos, JSONArray items)

Note that there is no way to call a non-static method from a static one directly (i.e. without calling it on an object/instance). Thus, if for any reason, you can't remove static keyword from the declaration of callBackPhoto, you are left with only two options:

  1. Declare build too as static

  2. Call build on an object/instance e.g. new PhotosActivity().build()

    Though any of these two options will solve your problem, I don't think this is how you intend to design your class.

Upvotes: 1

Scratte
Scratte

Reputation: 3166

Static

The static methods are alive all the time. They live from the class is loaded. They don't need objects to live. I think of them as not really belonging to the class, but the class is just a nice way to organize those methods (the same for variables). The methods could be put in any other class definition and it would still work. But organizing them in classes where they will be used make it easy to prevent access from other parts of the program, like other objects or other static methods. They are called class methods or class variables.

Instance

The non-static "stuff" does not live unless there is an object. That's why you cannot call below methodOne or methodTwo from the static methods. You have to create an object first. They are called instance methods or instance variables, because you need an instance of an object to call them.

Error

error: non-static method <methodname> cannot be referenced from a static context basically means "There's no object"

Example

public class StackOverflowTest {
  public static void main(String[] args) {  // this is just another static method
//    methodOne();                            // error. There's no object

    StackOverflowTest test = new StackOverflowTest(); 
    test.methodOne();                       // method called on object.
  }

  // methods live outside objects
  static void staticMethodOne() {
    System.out.println("staticMethodOne");
    staticMethodTwo();                      // no object required.
  }
  static void staticMethodTwo() { 
    System.out.println("staticMethodTwo");
//    methodTwo();                            // error. There's no object
  }

  // methods that only live inside objects
  void methodOne() {                        // method can only be invoked if there's an object.
    System.out.println("methodOne");
    methodTwo();                            // no problem. Already inside the object.
  }
  void methodTwo() {
    System.out.println("methodTwo");
    staticMethodTwo();                      // no problem. Objects can access static methods.
  }
}

Your case

So you either have to create a PhotosActivity object inside your build(), or you have to make callBackPhoto a static method. I can't see what your render does, but it's the same principle.

Upvotes: 0

Nate T
Nate T

Reputation: 861

In java, a static method belongs to EVERY object of the class that defines it. Therefore, you can call it from the parent class without creating an object like so:

ParentClass.myMethod;

However, this is not the case the case with instance (non-static) methods. To call this type of method, you need to define it in a class, create an object from that class, and then call it from that object, like this:

//inside ParentClass definition
public void myMethod(){bla bla;}
//In some other class
ParentClass obj = new ParentClass;
obj.myMethod;

Suppose you have code calling a static member of a class without creating an instance of that class. If that method contained a non-static method, there would be no object in memory to call it on. This is why it isn't possible.

Upvotes: 0

Related Questions