0

I have a problem with callback an activity, as the main activity. My story is that I get a list of branches from an `API then I pass the list back to activity to make a RecyclerView.

I should say that I don't have a problem with the TextView, for example, to show one item, but I get this error when debugging this line:

branchRecyclerView.setAdapter(branchAdapter);

The error is:

Only the original thread that created a view hierarchy can touch its views.

EDIT:

There is a solution by using Runnable method. But I don't know how to use it because of these reasons:

  1. I use WebApi to get information by using OkHttp. OnResponse of this library return void, so I should callback a method in Activity_Main to create a list.

  2. For solving No.1, I pass Main_Activity variable as a constructor parameter to this class.

  3. I want to use Runnable as a solution in activity_main to create object from my API class and call my API

  4. That constructor in No.3 only accept parameter as a Runnable class! So I can't pass this to it and I have to pass nothing! So I get this error: incompatible types: < anonymous Runnable > cannot be converted to MainActivity

My codes (with some reduction):

Main_Activity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
try {
            CentralAPIs api = new CentralAPIs();
            api.run();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
}
public void generateBranchList(List<BranchModel> branches) {
    RecyclerView branchRecyclerView;
    RecyclerView.Adapter branchAdapter;
    RecyclerView.LayoutManager branchLayoutManager;
    branchRecyclerView = (RecyclerView) findViewById(R.id.branchRecycleView);   
    try {
        branchLayoutManager = new LinearLayoutManager(this);
        branchRecyclerView.setLayoutManager(branchLayoutManager);        
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

CentralAPI

MainActivity activity;
public CentralAPIs(MainActivity activity){
    this.activity = activity;
}

public void onResponse(Call call, Response response) throws IOException {
    if (!response.isSuccessful())
        throw new IOException("Unexpected code " + response);
    Headers responseHeaders = response.headers();
    for (int i = 0, size = responseHeaders.size(); i < size; i++) {
        System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
    }
    Gson gson = new GsonBuilder()
            .setLenient()
            .create();
    try {
        List<BranchModel> branches = gson.fromJson(response.body().charStream(),ArrayList.class);
        //********** HERE CALLBACK ACTIVITY METHOD ****************
        activity.generateBranchList(branches);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

Adapter

public class BranchAdapter extends RecyclerView.Adapter<BranchAdapter.BranchViewHolder>{    
    private List<BranchModel> branchList;
    public static class BranchViewHolder extends RecyclerView.ViewHolder {            
        public View currentView;
        public BranchViewHolder(View currentView) {
            super(currentView);
            this.currentView = currentView;
        }
    }

    public BranchAdapter(List<BranchModel> branchList) {
        this.branchList = branchList;
    }

    @Override
    public BranchViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_main, viewGroup, false);
        BranchViewHolder pvh = new BranchViewHolder(v);
        return pvh;
    } 

    @Override
    public int getItemCount() {
        return branchList.size();
    }
}
Community
  • 1
  • 1
Siamak Ferdos
  • 3,181
  • 5
  • 29
  • 56
  • 1
    Possible duplicate of [Android "Only the original thread that created a view hierarchy can touch its views."](http://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi) – David Medenjak May 14 '17 at 11:07
  • Why are you setting `branchRecyclerView.setLayoutManager(branchLayoutManager);` and `branchRecyclerView.setHasFixedSize(true);` multiple times? I think that might be the problem. – Shashanth May 14 '17 at 14:33
  • @DavidMedenjak This example is about running code in same class so there's not any problem if I want create UI in same class! But if Iwant separate class which run an Async method I face to problems which I put im my edit part. – Siamak Ferdos May 15 '17 at 08:15
  • @DavidMedenjak I found where is the problem, it not relevant to `Runnable`, so it's not duplicate! – Siamak Ferdos May 17 '17 at 04:49

1 Answers1

0

Finally, I got what's the problem with my code. I thought that binding occurs after a source be made and inject to view, but I mistook! It should be bind before calling the method which gets data from API. By binding in other methods it runs out the main thread. So it's not relevant to Runnable class!

By moving these code from generateBranchList to OnCreate, the problem is solved.

RecyclerView.LayoutManager branchLayoutManager;
branchRecyclerView = (RecyclerView) findViewById(R.id.branchRecycleView);
branchLayoutManager = new LinearLayoutManager(this);
branchRecyclerView.setLayoutManager(branchLayoutManager);
Siamak Ferdos
  • 3,181
  • 5
  • 29
  • 56