2017-08-14 68 views
0

我有一个MapsActivity在我的应用程序上显示Google地图。 我有一个文本文件,我有街道名称,邮政编码和城市名称。我使用BufferedReader读取这个文本文件。我的文本文件中有近100条街道。所以,我以编程方式在Google Map中添加了近100个标记。这需要时间,这取决于互联网连接。AsyncTask零星地工作Android

因此我决定使用AsyncTask。因为我知道,这个UI的东西不能在doInBackground中完成,我把readfile()方法(它增加了这100个标记)作为一个可运行的线程在doInBackground中。我不希望用户看到空白屏幕,因此我添加了一个ProgressBar。

这里是问题:进度条并不总是工作,它并不总是看到,它是偶尔看到,这使我的假设,我的Asycntask有什么问题。也许我称之为AsyncTask的方式很糟糕。请看看我的代码。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { 
private GoogleMap mMap; 
String city, adress, zip; 
LatLngBounds.Builder builder = new LatLngBounds.Builder(); 


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


    setContentView(R.layout.activity_maps); 

    // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(map); 
    mapFragment.getMapAsync(this); 


} 


@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 

    new Test().execute(null,null,null); //calling AsyncTask 

} 


public void readFile() { 

    Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault()); 
    List<Address> address; 
    LatLng p2; 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt"))); 
     String line; 

     while ((line = reader.readLine()) != null) { 

      String splittedLine[] = line.split(","); 
      int numberofElements = 2; 
      String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements); 

      if (address.size() !=0) { 

       Address location = address.get(0); 
       location.getLatitude(); 
       location.getLongitude(); 

       p2 = new LatLng(location.getLatitude(), location.getLongitude()); 

       mMap.addMarker(new MarkerOptions().position(p2).title("Location " + onlyAdressandZip[0]+"," + onlyAdressandZip[1])); 
       builder.include(p2); 

       LatLngBounds bounds = builder.build(); 
       mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20)); 

      } 

       } 

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

} 


public class Test extends AsyncTask<Void, Void, Void>{ 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // what to do before background task 
     dialog = new ProgressDialog(MapsActivity.this); 
     dialog.setTitle("Loading..."); 
     dialog.setMessage("Please wait."); 
     dialog.setIndeterminate(true); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 



    @Override 
    protected Void doInBackground(Void... params) { 
     runOnUiThread(new Runnable() { 
      public void run() { 

       readFile(); 

      } 
     }); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void foo) { 
    super.onPostExecute(foo); 
    dialog.cancel(); 

    } 
} 
} 
+1

你试图在工人线程执行uithread。你应该在后台读取文件并使用'onProgressUpdate()'(它通过调用'publishProgress()')在uithread中运行来更新进度条。阅读更多关于[AsyncTask in here](https://developer.android.com/reference/android/os/AsyncTask.html).. –

+0

@MatiasOlocco你能告诉我一个代码示例吗? – ckbln

+1

在文档中有一个完美的工作示例,请阅读它。 –

回答

1

所以,正如我在评论说,在这个例子中,基本上我重新写你的异步任务在后台运行的文件的读取和更新的uithread地图的进步。代码远不是最终的,但你应该测试和改进它。

因为AsyncTask为您提供更新uithreads的工具,所以您绝对不应该在那里使用runOnUiThread()

doc说:

的AsyncTask能够正确且容易使用的UI线程。这个类 允许您执行后台操作并在UI线程上发布结果,而无需操作线程和/或处理程序。

的例子:

public class Test extends AsyncTask<Void, WrapperObject, Void> { 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // what to do before background task 
     dialog = new ProgressDialog(MapsActivity.this); 
     dialog.setTitle("Loading..."); 
     dialog.setMessage("Please wait."); 
     dialog.setIndeterminate(true); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 


    @Override 
    protected Void doInBackground(Void... params) { 

     Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault()); 
     List<Address> address; 
     LatLng p2; 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt"))); 
      String line; 

      while ((line = reader.readLine()) != null) { 

       String splittedLine[] = line.split(","); 
       int numberofElements = 2; 
       String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements); 

       if (address.size() != 0) { 

        Address location = address.get(0); 
        location.getLatitude(); 
        location.getLongitude(); 

        p2 = new LatLng(location.getLatitude(), location.getLongitude()); 
        builder.include(p2); 

        WrapperObject wrapperObject = new WrapperObject(); 
        wrapperObject.bounds = builder.build(); 
        wrapperObject.latlng = p2; 
        wrapperObject.onlyAdressandZip = onlyAdressandZip; 
        publishProgress(wrapperObject); 
       } 

      } 

     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
     return null; 
    } 

    protected void onProgressUpdate(WrapperObject... wrapperObjects) { 
     WrapperObject wrapperObject = wrapperObjects[0]; 
     mMap.addMarker(new MarkerOptions().position(wrapperObject.latlng).title("Location " + wrapperObject.onlyAdressandZip[0]+"," + wrapperObject.onlyAdressandZip[1])); 
     mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(wrapperObject.bounds, 20)); 
    } 

    @Override 
    protected void onPostExecute(Void foo) { 
     super.onPostExecute(foo); 
     dialog.cancel(); 
    } 
} 
//this is a wrapper to update the progress, you should make this better.  
public static class WrapperObject { 
    public LatLng latlng; 
    public LatLngBounds bounds; 
    public String[] onlyAdressandZip; 
} 
+0

Ohshit,真的有效。我真的很感激你的帮助:) – ckbln

+0

很高兴帮助!请确保您阅读并理解文档。知道未来如何使用Asynctasks非常重要。 –