3

У меня есть MainActivity, который имеет две вкладки на ActionBar. Моя основная компоновка этого действия - пустой FrameLayout. Первая вкладка содержит ProgressBar, вторая - Button, которая начинает загрузку файлов. Вот SettingsTab:Установить прогресс на ProgressBar в другом классе

public class SettingsTab extends Fragment { 
    private Button downloadButton; 
    private ImagesTab imagesTab; 
    private static String fileDir = "sdcard/AndroidCourse/"; 
    public void downloadImages(String url,int limit,String imageExtension) 
    { 

     try { 
      StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 
      .detectAll() 
      .build()); 
      Document doc = Jsoup.connect(url).get(); 
      StringBuilder sb = new StringBuilder("img[src$=."); 
      sb.append(imageExtension); 
      sb.append("]"); 
      Elements images = doc.select(sb.toString()); 
      ArrayList<String> urls = new ArrayList<String>(); 
      for(Element image : images) { 
       if(urls.size() == limit) { 
        break; 
       } 
       urls.add(image.attr("src")); 
      } 
      Log.e("urls", String.valueOf(urls.size())); 
      imagesTab.downloadStarted(urls); 


     } catch (IOException e) { 
      Log.e("SettingsTab", e.getMessage()); 
     } 
    } 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.settings_tab, null); 
     downloadButton = (Button) view.findViewById(R.id.startButton); 
     imagesTab = new ImagesTab(); 
     downloadButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       downloadImages("http://www.google.com",5,"jpg"); 


      } 

     }); 
     return view; 

    } 
} 

и ImagesTab:

public class ImagesTab extends Fragment { 
    ProgressBar downloadProgressBar; 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.images_tab, null); 
     downloadProgressBar = (ProgressBar) view.findViewById(R.id.downloadProgressBar); 
     //downloadProgressBar.setVisibility(View.INVISIBLE); 

     return view; 

    } 
    public void downloadStarted(ArrayList<String> urls) 
    { 
     //downloadProgressBar.setVisibility(View.VISIBLE); 
     Intent intent = new Intent(getActivity(), DownloadService.class); 
     intent.putExtra("urls", urls); 
     intent.putExtra("receiver", new DownloadReceiver(new Handler())); 
     getActivity().startService(intent); 
     Toast.makeText(getActivity(), "Service started!" + urls.size(), Toast.LENGTH_SHORT).show(); 
    } 
    private class DownloadReceiver extends ResultReceiver{ 
     public DownloadReceiver(Handler handler) { 
      super(handler); 
     } 

     @Override 
     protected void onReceiveResult(int resultCode, Bundle resultData) { 
      super.onReceiveResult(resultCode, resultData); 
      if (resultCode == DownloadService.UPDATE_PROGRESS) { 
       int progress = resultData.getInt("progress"); 
       downloadProgressBar.setProgress(progress); 
       if (progress == 100) { 
        downloadProgressBar.setVisibility(View.INVISIBLE); 
       } 
      } 
     } 
    } 
} 

Когда я нажимаю StartDownloadButton, сбои приложения со следующим исключением:

11-26 03:55:55.765: E/AndroidRuntime(21200): FATAL EXCEPTION: main 
11-26 03:55:55.765: E/AndroidRuntime(21200): java.lang.NullPointerException 
11-26 03:55:55.765: E/AndroidRuntime(21200): at android.content.ComponentName.<init>(ComponentName.java:75) 
11-26 03:55:55.765: E/AndroidRuntime(21200): at android.content.Intent.<init>(Intent.java:3227) 
11-26 03:55:55.765: E/AndroidRuntime(21200): at com.example.lista2.ImagesTab.downloadStarted(ImagesTab.java:32) 
11-26 03:55:55.765: E/AndroidRuntime(21200): at com.example.lista2.SettingsTab.downloadImages(SettingsTab.java:55) 
11-26 03:55:55.765: E/AndroidRuntime(21200): at com.example.lista2.SettingsTab$1.onClick(SettingsTab.java:72) 

Кто-нибудь есть идеи, как для изменения хода ProgressBar в разных частях приложение?

ответ

0

Основная проблема в вашем коде, и причина этого является NullPointerException линией:

imagesTab = new ImagesTab(); 

где экземпляр нового ImagesTabFragment. Проблема в том, что этот новый экземпляр Fragment не привязан к Activity (он находится в «воздухе»), поэтому его метод getActivity() возвращает null. Это значение null из метода getActivity() вы переходите на Intent, которое вы строите в методе downloadStarted(), который выкинет NulPointerException. Вместо создания экземпляра ImgesTab, как и вы, вы должны получить ссылку на другой фрагмент, который уже (скорее всего) в родительской активности, используя getFragmentManager() и поиск фрагмента на основе его тега.

Во-вторых, обновление ProgressBar кажется скорее проблемой дизайна приложения. Например, почему у вас есть Button, который запускает загрузку на вкладке и ProgressBar, которая показывает ход загрузки на другой вкладке? Кроме того, вы, кажется, используете Service для загрузки, поэтому вместо того, чтобы делать вкладки, вы должны действительно сделать Service, который загружает файлы, а фрагмент нужной вкладки (с ProgressBar) общается. Это можно сделать очень просто, сделав Service для отправки трансляции на определенных уровнях загрузки и сделав ваш Activity (который содержит два фрагмента вкладок), динамически регистрируя BroadcastReceiver. Когда Service отправляет широковещательную рассылку (например, на 10%), Activity 'BroadcastReceiver выберет его (если он будет жив), а затем он обновит ProgressBar от нужного Fragment, если в этот момент видна Fragment.

Смежные вопросы