2013-06-28 3 views
0

Прежде всего, я относительно новичок в программировании для Android.AsynkTask внутри фрагмента в ViewPager

Я создаю приложение ViewPager с двумя фрагментами. Один из фрагментов запрашивает данные с сервера и возвращает результат в основной файл FragmentActivity. Моя проблема заключается в том, что этот запрос на сервер может занять некоторое время, и я пытался получить ProgressDialog для отображения в AsyncTask, пока пользователь ждет получения данных. Когда я создаю фоновый поток для извлечения данных, я успешно выполняю некоторый код в методе onPostExecute() и устанавливаю некоторые переменные. Тем не менее, оператор возврата, который отправляет информацию обратно в FragmentActivity, выполняется до того, как фактический поток заканчивается. Кажется, я не могу понять, как основной поток ждать в фоновом потоке. Использование метода get() Asyctask приводит к появлению сообщения ProgressDialog. Я просмотрел много сообщений здесь, но не могу найти ответа.

Все, что угодно.

код ниже:

SplashScreen.java

public class SplashScreen extends FragmentActivity { 
    MainMenu mainMenu; 
    MapScreen mapScreen; 
    PagerAdapter pagerAdapter; 
    ViewPager viewPager; 
    List<LatLng> geoPoints; 
    private Context context; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      requestWindowFeature(Window.FEATURE_NO_TITLE); 
      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

      setContentView(R.layout.activity_splash_screen); 
      context = this; 

      initializePaging(); 
    } 

    private void initializePaging() 
    { 
      mainMenu = new MainMenu(); 
      mapScreen = new MapScreen(); 

      pagerAdapter = new PagerAdapter(getSupportFragmentManager()); 
      pagerAdapter.addFragment(mainMenu); 
      pagerAdapter.addFragment(mapScreen); 

      viewPager = (ViewPager) super.findViewById(R.id.viewPager); 
      viewPager.setAdapter(pagerAdapter); 
      viewPager.setOffscreenPageLimit(2); 
      viewPager.setCurrentItem(0); 

      viewPager.setOnPageChangeListener(new OnPageChangeListener() 
      { 
        @Override 
        public void onPageScrollStateChanged(int postion){} 
        @Override 
        public void onPageScrolled(int arg0, float arg1, int arg2){} 
        @Override 
        public void onPageSelected(int position) 
        { 
        switch(position){ 
          case 0: findViewById(R.id.first_tab).setVisibility(View.VISIBLE); 
            findViewById(R.id.second_tab).setVisibility(View.INVISIBLE); 
            break; 

          case 1:  findViewById(R.id.first_tab).setVisibility(View.INVISIBLE); 
            findViewById(R.id.second_tab).setVisibility(View.VISIBLE); 
            break; 
          } 
        } 
      }); 
} 

    //Called from onClick in main_mainu.xml 
    public void getDirections(View view) 
    { 
      InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
      inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 

      try 
      { 
        geoPoints = mainMenu.getDirections(context); 
        mapScreen.plotPoints(geoPoints); 

      } 
      catch(Exception e) 
      { 
        Toast.makeText(getApplicationContext(), "Error! Invalid address entered.", Toast.LENGTH_LONG).show(); 
        mainMenu.clear(); 
      } 

    } 

}

MainMenu.java

public class MainMenu extends Fragment { 

    String testString; 
    int testInt; 
    TextView testTV; 
    private TextView tvDisplay; 
    private EditText departure; 
    private EditText destination; 
    private Geocoder geocoder; 
    private List<Address> departAddress; 
    private List<Address> destinationAddress; 
    private List<LatLng> geoPoints; 
    private String departString; 
    private String destinationString; 
    private Address departLocation; 
    private Address destinationLocation; 
    private LatLng departurePoint; 
    private LatLng destinationPoint; 
    private Context contextMain; 
    private GetData task; 

    public MainMenu() 
    { 
      super(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
      View root = (View) inflater.inflate(R.layout.main_menu, null); 

      geoPoints = new ArrayList<LatLng>(2); 

      return root; 
    } 

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) 
    { 
      departure = (EditText) getView().findViewById(R.id.depart_field); 
      destination = (EditText) getView().findViewById(R.id.destination_field); 

      tvDisplay = (TextView) getView().findViewById(R.id.textView1); 

    } 

    public List<LatLng> getDirections(Context context) 
    {  
      contextMain = context; 
      geocoder = new Geocoder(getActivity()); 

      departString = departure.getText().toString(); 
      destinationString = destination.getText().toString(); 

      try 
      { 
        task = new GetData(new Callback(){ 
          public void run(Object result) 
          { 
            //return geoPoints; 
          } 
        }); 
        task.execute((Void[])null); 
      }catch(Exception e) 
      { 
        e.printStackTrace(); 
      } 

      return geoPoints; 
    } 

    public void clear() 
    { 
      departure.setText(""); 
      destination.setText(""); 
      tvDisplay.setText("Enter departure point, and destination point"); 
    } 

    private class GetData extends AsyncTask<Void, Void, List<List<Address>>> 
    { 
      Callback callback; 
      private ProgressDialog processing; 

      public GetData(Callback callback) 
      { 
        this.callback = callback; 
      } 

      @Override 
      protected void onPreExecute() 
      { 
        processing = new ProgressDialog(contextMain); 
        processing.setTitle("Processing..."); 
        processing.setMessage("Please wait."); 
        processing.setCancelable(false); 
        processing.setIndeterminate(true); 
        processing.show(); 

      } 

      @Override 
      protected List<List<Address>> doInBackground(Void...arg0) 
      {  
        List<List<Address>> list = new ArrayList<List<Address>>(2); 

        try 
        { 
          departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022); 
          destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022); 

          list.add(departAddress); 
          list.add(destinationAddress); 

        }catch(IOException e) 
        { 
          e.printStackTrace(); 
        } 

        return list; 
      } 

      @Override 
      protected void onPostExecute(List<List<Address>> list) 
      { 
        departLocation = list.get(0).get(0); 
        destinationLocation = list.get(1).get(0); 

        departurePoint = new LatLng(departLocation.getLatitude(), departLocation.getLongitude()); 
        destinationPoint = new LatLng(destinationLocation.getLatitude(), destinationLocation.getLongitude()); 

        if(geoPoints.size() >= 2) 
        { 
          geoPoints.clear(); 
        } 

        geoPoints.add(departurePoint); 
        geoPoints.add(destinationPoint); 

        callback.run(list); 
        processing.dismiss(); 
      } 
    } 

}

+0

Кто-нибудь знает, что я делаю неправильно здесь? –

ответ

1
 @Override 
     protected Object doInBackground(Void...arg0) 
     { 
       Object result = null; 

       try 
       { 
         departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022); 
         destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022); 

       }catch(IOException e) 
       { 
         e.printStackTrace(); 
       } 

       return result; 
} 

Вы никогда не устанавливаете значение результата ...

+0

Другое дело. Вы могли бы подумать о том, чтобы сетевая задача была включена в компонент локальной службы. Таким образом, если пользователь поворачивает экран, вы случайно не создадите еще один рабочий поток AsyncTask, когда снова будет заново создано действие. –

+0

Я обновил класс MainMenu, но все же кажется, что проблема остается; оператор return в методе getDirections() выполняется до завершения AsyncTask. –