Backendless: я не могу получить доступ к полученным данным

Используя проект Android здесь, RestaurantListActivity показывает список извлеченных Restaurants из Restaurant таблиц в Backendless, и проблем нет. уже.

Проблема: эти два дня я пытался получить список ресторанов где-то еще в коде или использовать список totalRestaurants.

Я пытался:

1- Этот код вызывает исключение NullPointerException:

Backendless.Data.of( Restaurant.class ).findFirst();

2- используя тот же код в Github: я могу получить доступ к списку totalRestaurants внутри скобок, но после этого блока кода он показывает мне, что список totalRestaurants пуст.

Backendless.Data.of( Restaurant.class ).find( query, new LoadingCallback<BackendlessCollection<Restaurant>>( this, getString( R.string.loading_restaurants ), true )
    {
      @Override
      public void handleResponse( BackendlessCollection<Restaurant> restaurantsBackendlessCollection )
      {
        restaurants = restaurantsBackendlessCollection;

        addMoreItems( restaurantsBackendlessCollection );

        super.handleResponse( restaurantsBackendlessCollection );
      }
    } );

3- Использование автозагрузки на сайте Backendless с небольшими правками: снова происходит то же самое. Внутри обратного вызова я могу напечатать имя объекта Restaurant и добавить каждый объект в copylist, но в конце кода copylist пусто!

LoadingCallback<BackendlessCollection<Restaurant>> callback=new LoadingCallback<BackendlessCollection<Restaurant>>(this, getString( R.string.loading_restaurants ), true)
      {
          @Override
          public void handleResponse( BackendlessCollection<Restaurant> restaurants )
          {
              System.out.println( "Loaded " + restaurants.getCurrentPage().size() + " restaurant objects" );
              System.out.println( "Total restaurants in the Backendless storage - " + restaurants.getTotalObjects() );

              Iterator<Restaurant> iterator=restaurants.getCurrentPage().iterator();

              while( iterator.hasNext() )
              {
                  Restaurant restaurant=iterator.next();
                  copylist.add(restaurant);
                  System.out.println( "\nRestaurant name = " + restaurant.getName() );
              }
          }
      };
      Backendless.Data.of( Restaurant.class ).find( callback );

Ваша помощь очень ценится!


person Nora Alnashwan    schedule 14.03.2016    source источник


Ответы (3)


Хорошо, вот что я сделал:

Класс TaxiList с геттерами и сеттерами

public class TaxiList {

private String ime; //in database
private String telefon1; //in database
private String telefon2; //in database

public String getIme(String ime) {
    return this.ime;
}

public void setIme(String ime) {
    this.ime = ime;
}

public String getTelefon1(String telefon1) {
    return this.telefon1;
}

public void setTelefon1(String telefon1) {
    this.telefon1 = telefon1;
}

public String getTelefon2(String telefon2) {
    return this.telefon2;
}

public void setTelefon2(String telefon2) {
    this.telefon2 = telefon2;
}

}

Далее адаптер

public class TaxiAdapter extends BaseAdapter {

private final LayoutInflater inflater;
private List<TaxiList> taxiLists = null;

public TaxiAdapter(Context context,List<TaxiList> taxiLists) {

    Context mContext = context;
    this.taxiLists = taxiLists;
    inflater = LayoutInflater.from(mContext);

}

public class ViewHolder {

    TextView ime;
    TextView telefon1;
    TextView telefon2;

}

@Override
public int getCount() {
    return taxiLists.size();
}

@Override
public TaxiList getItem(int position) {
    return taxiLists.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

public View getView(final int position, View view, ViewGroup parent) {
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.one_row_taxi, parent, false);

        holder.ime = (TextView) view.findViewById(R.id.textIme);
        holder.telefon1 = (TextView) view.findViewById(R.id.textTelefon1);
        holder.telefon2 = (TextView) view.findViewById(R.id.textTelefon2);


        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }

    holder.ime.setText(taxiLists.get(position).getIme("ime"));
    holder.telefon1.setText(taxiLists.get(position).getTelefon1("telefon1"));
    holder.telefon2.setText(taxiLists.get(position).getTelefon2("telefon2"));


    return view;
}

}

И, наконец, вот как вы извлекаете данные из Backendless (для меня во фрагменте)

public class Taxi extends Fragment {

private ListView listview;
private ProgressBar progressBar;
private List<TaxiList> taxiLists = new ArrayList<>();

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_taxi, container, false);

    listview = (ListView) rootView.findViewById(R.id.listview);

    progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);

    progressBar.setVisibility(View.VISIBLE);

    BackendlessDataQuery query = new BackendlessDataQuery();

    QueryOptions queryOptions = new QueryOptions();

    String whereClause = "created";

    queryOptions.addSortByOption(whereClause);

    query.setQueryOptions(queryOptions);

    Backendless.Data.of(TaxiList.class).find(query, new AsyncCallback<BackendlessCollection<TaxiList>>() {

        @Override
        public void handleResponse(BackendlessCollection<TaxiList> taxiListBackendlessCollection) {

            TaxiList taxiList;
            for (TaxiList total : taxiListBackendlessCollection.getCurrentPage()) {

                taxiList = new TaxiList();
                taxiList.setIme(total.getIme("ime"));
                taxiList.setTelefon1(total.getTelefon1("telefon1"));
                taxiList.setTelefon2(total.getTelefon2("telefon2"));

                taxiLists.add(taxiList);

                TaxiAdapter adapter = new TaxiAdapter(getActivity(), taxiLists);

                listview.setAdapter(adapter);

                progressBar.setVisibility(View.GONE);

            }
        }

        @Override
        public void handleFault(BackendlessFault backendlessFault) {
        }
    });

    return rootView;

}

}

Надеюсь, это поможет вам :)

person Srdan    schedule 16.03.2016

(1) Предоставьте трассировку стека, без подробностей будет сложно диагностировать проблему.

(2) и (3) Имейте в виду, что выполнение метода handleResponse является асинхронным. Если вы попытаетесь получить доступ к "ресторанам" или "copyList" до вызова метода "handleResponse", данных там просто не будет.

person Mark Piller    schedule 15.03.2016
comment
Глядя на ваше имя, я думаю, что именно вы делаете уроки, за что мы благодарны. Я понял, что (1) является синхронным и не может быть выполнено на Android. Я понял вашу точку зрения по поводу (2) и (3), но как узнать, когда в это время выполняется ответ дескриптора для доступа к ресторанам? - person Nora Alnashwan; 15.03.2016
comment
Код, который вы показали для (1), не является синхронным. API синхронизации будет иметь аргумент AsyncCallback в методе findFirst. В Java есть способы синхронизации выполнения потоков с помощью блокировки объектов, защелок или семафоров. В качестве альтернативы вы можете создать новый поток и внутри него использовать синхронные API. - person Mark Piller; 15.03.2016
comment
Извините за мою ошибку и спасибо за объяснение. Я новичок в блокировке объектов, защелках и семафорах в Java. Я постараюсь глубоко понять эти предметы, прежде чем использовать их. В этот момент я добился того, чего хочу, другим простым способом и представил его в качестве ответа. Ваша помощь приветствуется. - person Nora Alnashwan; 16.03.2016

Создайте сериализуемый класс

public class SharedClass implements Serializable{
    public List<String> copylist = new ArrayList<>();

    void additem(String s){
        copylist.add(s);
    }
}

Поскольку handleResponse в вызовах (2) добавить addMoreItems. Отредактируйте его, чтобы заполнить copylist и перейти к другому действию под названием NewActivity.

private void addMoreItems( BackendlessCollection<Restaurant> nextPage )
  {
    totalRestaurants.addAll( nextPage.getCurrentPage() );
    Intent restaurantListingIntent = new Intent( this, NewActivity.class );

    SharedClass sharedlist=new SharedClass();
    for(int i=0;i<totalRestaurants.size();i++){
        sharedlist.additem(totalRestaurants.get(i).getName());
        System.out.println("Added "+totalRestaurants.get(i).getName());
    }

    restaurantListingIntent.putExtra("sharedlist", sharedlist);
    startActivity(restaurantListingIntent);
  }

Внутри NewActivity печатаю размер copylist

Intent intent=getIntent();
SharedClass sharedObject= (SharedClass) intent.getSerializableExtra("sharedlist");
System.out.println("copy list size"+ sharedObject.copylist.size());
person Nora Alnashwan    schedule 16.03.2016