2013-06-28 82 views
0

首先,我對android編程比較陌生。AsynkTask在ViewPager中的片段內

我正在用兩個片段創建一個ViewPager應用程序。其中一個片段從服務器請求數據並將結果返回給主FragmentActivity。我的問題是,這個對服務器的請求可能需要一段時間,並且我一直試圖讓用戶在等待數據被檢索時使用AsyncTask顯示ProgressDialog。一旦我創建後臺線程來檢索數據,我在onPostExecute()方法中成功執行了一些代碼並設置了一些變量。但是,在後臺線程實際結束之前正在執行將信息發送回FragmentActivity的返回語句。我似乎無法找出主線程等待後臺線程的方法。使用Asyctask的get()方法會導致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類,但似乎仍然存在問題;在AsyncTask完成之前,getDirections()方法中的return語句正在執行。 –