Witam,
mam problem otóż nie wiem jak sobie poradzić z problemem odświeżania fragmentów w androidzie. Tworzę aplikację która w domysle pobiera co 30 sekund dane z internetu i chciałem je umieszczać w ListView na jednym z Fragmentów, problem w tym że stworzyłem sobie Thread który się tym zajmuję i sprawdziłem i te wartości faktycznie są pobierane i przechowywane w odpowiednim miejscu nie zmienia się nic na ekranie. Wartości nadal zostają stare, chyba że przejdę dwie zakładki dalej(dwa taby dalej) i wrócę to wtedy wartości są zaktualizowane, czy orientuje się ktoś jak to działa i jak sobie z tym poradzić?
- Rejestracja:ponad 9 lat
- Ostatnio:ponad 9 lat
- Postów:7
- Rejestracja:ponad 9 lat
- Ostatnio:ponad 9 lat
- Postów:7
MainActivity
private TabHost tabHost;
private ViewPager viewPager;
public MyFragmentPagerAdapter myViewPagerAdapter;
class FakeContent implements TabContentFactory {
private final Context mContext;
public FakeContent(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumHeight(0);
v.setMinimumWidth(0);
return v;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs_viewpager_layout);
pobieranie_wartosci.start();
//this starts Thread for updating data
// init tabhost
this.initializeTabHost(savedInstanceState);
// init ViewPager
this.initializeViewPager();
}
private void initializeViewPager() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(new Tab1Fragment());
fragments.add(new Tab2Fragment());
fragments.add(new Tab1Fragment());
fragments.add(new Tab1Fragment());
fragments.add(new Tab3Fragment());
fragments.add(new Tab1Fragment());
this.myViewPagerAdapter = new MyFragmentPagerAdapter(
getSupportFragmentManager(), fragments);
this.viewPager = (ViewPager) super.findViewById(R.id.viewPager);
this.viewPager.setAdapter(this.myViewPagerAdapter);
this.viewPager.setOnPageChangeListener(this);
onRestart();
@Override
public void onTabChanged(String tabId) {
int pos = this.tabHost.getCurrentTab();
this.viewPager.setCurrentItem(pos);
HorizontalScrollView hScrollView = (HorizontalScrollView) findViewById(R.id.hScrollView);
View tabView = tabHost.getCurrentTabView();
int scrollPos = tabView.getLeft()
- (hScrollView.getWidth() - tabView.getWidth()) / 2;
hScrollView.smoothScrollTo(scrollPos, 0);
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int position) {
this.tabHost.setCurrentTab(position);
}
}
i teraz wątek który domyślnie miał aktualizować dane:
Thread pobieranie_wartosci = new Thread()
{
public void run()
{
while(true)
{
int r = zmienne.lista_moich_spolek.size()-1;
for(int i =0; i<=r;i++){
try
{
zmienne.lista_moich_spolek.get(i).transformacja_ceny(new Cena().execute(zmienne.lista_moich_spolek.get(i).numer).get());
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
zmienne.lista_moich_spolek.get(0).cena_kupna++;
myViewPagerAdapter.notifyDataSetChanged();
System.out.println("cena :" + zmienne.lista_moich_spolek.get(0).cena_kupna);
}
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
FragmentPageAdapter
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
List<Fragment> fragments;
public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
Fragment
public class Tab2Fragment extends Fragment {
private ArrayList<HashMap<String, String>> list;
public static final String FIRST_COLUMN="First";
public static final String SECOND_COLUMN="Second";
public static final String THIRD_COLUMN="Third";
public static final String FOURTH_COLUMN="Fourth";
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.spolki_portfel, container, false);
final ListView listView=(ListView) v.findViewById(R.id.listView1);
list=new ArrayList<HashMap<String,String>>();
LayoutInflater inflater1 = getActivity().getLayoutInflater();
View header = inflater1.inflate(R.layout.naglowek_wlasne_spolki, listView, false);
listView.addHeaderView(header);
ListViewAdapter adapter=new ListViewAdapter(getActivity(), list);
listView.setAdapter(adapter);
return v;
}
}
Postarałem się powycinać jak najwięcej treści żeby zostawić sam szkielet, jeśli coś jeszcze potrzeba to prosze pisać. Tab2Fragment zawiera ListView którą chciałbym aktualizować co 30 sekund, a wątek który domyslnie miał odświeżać znajduje się w MainActivity

- Rejestracja:prawie 17 lat
- Ostatnio:około 2 godziny
zmienne.lista_moich_spolek.get(i).transformacja_ceny(new Cena().execute(zmienne.lista_moich_spolek.get(i).numer).get());
Mistrzostwo świata. Wołam @Koziołek @niezdecydowany LINCZUJCIE!






- Rejestracja:prawie 17 lat
- Ostatnio:około 2 godziny
@Picrors jest to jakieś wyjście. Generalnie powinieneś wysłać komunikat żeby zrobić update view. Masz masakrę w kodzie, ale idąc na łatwiznę odpowiedź na Twoje pytanie to tak. Zastanawia mnie jedno. Wiedziałeś żeby użyć tego do myViewPagerAdapter ale nie wpadłeś na to żeby dołożyć to do adapter? Coś mi się wydaje że bezmyślne kopiowanie poszło w ruch.
Pozwolę sobie przejechać się tylko po tym nieszczęsnym wątku. po pierwsze w androidzie istnieje ScheduledExecutorService
(http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html), który wykona za ciebie jakieś 80% pracy związanej z tym wątkiem.
Po drugie pętla. Jak rozumiem lista_moich_spolek
ma typ z drzewa Collection
. Zamiast zwykłego for
-a należy zatem użyć foreach
ALBO while
z iteratorem. Rozwiązanie w obecnej formie jest w miarę poprawne wydajnościowo tylko w przypadku gdy masz pod spodem kolekcję o stałym czasie dostępu np. ArrayList
. Poza tym czytelność leży.
Zastanawia mnie tu też klasa Cena
, której nazwa wskazuje raczej na obiekt domenowy o dość ograniczonym zakresie obowiązków... suddenly pineapples... znaczy się metoda execute
. Jak już to opakuj ją w jakąś nazwę, która coś znaczy.
- Rejestracja:ponad 9 lat
- Ostatnio:ponad 9 lat
- Postów:7
tak, lista_moich_spolek jest ArrayListem. Jeśli chodzi o cenę jest to AsyncTask który parsuje i pobiera wartości indeksów spółek z sieci. Niestety literatura w języku polskim nie mówi wiele na ten temat więc nie wiem jak użyć narzędzi jak np. ScheduledExecutorService. Niestety przeniesienie wątku do Tab2Fragment też nie wiele pomogło.

Niestety literatura w języku polskim
, nie lubię tego mówić, ale najpierw podszkól angielski.

- Rejestracja:prawie 17 lat
- Ostatnio:około 2 godziny
To ja jeszcze pozwolę sobie dołożyć 3 grosze do tego co napisał @Koziołek.
ScheduledExecutorService
jak najbardziej. Problem polega na tym że on chce z tego wątku robić ViewUpdate. Niestety, jeśli nie oprze tego o Handler
to tego z innego wątku nie wykona, bo one nie mają dostępu do UIThread. Idąc tym tropem dalej, to może od razu użyłby dedykowanego rozwiązania do tego jakim jest AsyncTask
lub RxJava
. Oba te narzędzia tworzą nowy wątek przy okazji mając dostęp do UIThread, więc cała komunikacja między wątkimi odpada, co w przypadku tego "kodu" jest nawet wskazane.


- Rejestracja:prawie 17 lat
- Ostatnio:około 2 godziny
Picrors napisał(a):
W takim razie jakiego narzędzia powinienem spróbować użyć?
Myślę, że całkiem niezłym zestawem może okazać się:
- Głowa
- Internet
- Wszystkie informacje, które zostały w tym wątku napisane