我是新手程序员。我想从文件中读取数据并将其放在地图上。我想读取一个txt文件并在后台线程中执行,这是我的代码
MyTask mt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myFragmentManager = getSupportFragmentManager();
mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = mySupportMapFragment.getMap();
mt = new MyTask();
}
class MyTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(getAssets().open("example.txt")));
String temp;
while ((temp = br.readLine()) != null)
sb.append(temp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
String myjsonstring = sb.toString();
try {
JSONObject jsonObjMain = new JSONObject(myjsonstring);
JSONArray jsonArray = jsonObjMain.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObj = jsonArray.getJSONObject(i);
String name = jsonObj.getString("Adres");
JSONObject c = jsonArray.getJSONObject(i);
JSONObject phone = c.getJSONObject("location");
String lat = phone.getString("latitude");
String lon = phone.getString("longitude");
dLat=Double.parseDouble(lat);
dLon=Double.parseDouble(lon);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
myMap.addMarker(new MarkerOptions().position(new LatLng(dLat, dLon)).title(name));
dialog.dismiss();
}
}
在实际设备上使用此代码,什么也不会发生,也没有添加任何点。我怎么了
最佳答案
好吧,您实例化一个MyTask
对象(new MyTask()
),并将其分配给我认为整个上下文中的成员变量(mt =
),仅此而已。
这意味着在MyTask
变量中引用了mt
对象,仅此而已。
您需要执行(触发)任务才能运行:
mt.execute();
将此行放在您希望任务开始的位置。
有关
AsyncTask
以及如何使用它们的详细信息,请参见Android documentation。创建完成后,任务将非常简单地执行:
new DownloadFilesTask().execute(url1, url2, url3);
通常,请始终先查看那里,尤其是对于您不习惯的Android范例的基本用法。
至于
<Void, Void, Void>
部分,我不知道您对Java泛型有多熟悉,如果没有的话,您应该首先了解the concept。在这里
AsyncTask
可以定义3件事:doInBackGround()
方法接受的参数类型,onProgressUpdate()
方法接受的参数类型,最后onProgressUpdate()
方法接受的参数类型和方法返回。在您的情况下,您的AsyncTask既不使用也不返回任何参数,因此只需将这3种类型指定为
doInBackground()
类型(有关原因,请参见this other SO question)。您必须指定类型,因为Java是一种强(静态)类型的语言,否则您将无法编译代码。那么,这在哪里有用呢?
假设您要在另一个
Void
中执行相同的操作(异步读取文件中的数据),然后可以将Activity
定义移出其自己的文件,并在两个活动中重用MyTask
。可以,但是您希望在每个活动中从不同文件加载数据,因此MyTask
实例必须以某种方式将要读取的文件名作为参数。 MyTask
MyTask
然后将如下所示:protected Void doInBackground(String... params) {
final String fileName = params[0]; // note: in real life you should check the arguments are valid first
...
现在,您看到它采用了
doInBackground()
类型的参数。为了使编译器能理解这一点,并允许您活动中的代码在调用String
时将String
类型的参数传递给其MyTask
实例,必须这样声明execute()
:public class MyTask extends AsyncTask<String, Void, Void>
否则,将会有编译错误。
再次,检查Android doc以更广泛地使用这些类型参数。