我是新手程序员。我想从文件中读取数据并将它们放在地图上。我想读一个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();
}
}
在真实设备上使用此代码时,没有任何反应,也没有添加任何点。我的错是什么?
答案 0 :(得分:2)
好吧,你实例化一个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()
方法接受的参数的类型,参数类型 {{1>} 1}}方法接受,最后是onProgressUpdate()
方法接受的参数的类型,并且其onProgressUpdate()
方法返回。
在您的情况下,您的AsyncTask不会获取也不返回任何参数,因此您只需将这3种类型指定为doInBackground()
类型(请参阅this other SO question至于原因)。您必须指定类型,因为Java是一种强(静态)类型的语言,否则它无法编译您的代码。
那么这在哪里有用呢?
假设您想要在另一个Void
中执行相同的操作(异步读取文件中的数据),然后您可以将Activity
定义放在其自己的文件中,并重用{{1}在你的两个活动中。好的,但是您希望从每个活动中的不同文件加载数据,因此MyTask
实例必须以某种方式将文件名作为参数读取。 MyTask
MyTask
将如下所示:
MyTask
现在您看到它需要doInBackground()
类型的参数。为使编译器能够理解这一点,并允许活动中的代码在调用protected Void doInBackground(String... params) {
final String fileName = params[0]; // note: in real life you should check the arguments are valid first
...
时将String
类型的参数传递给String
个实例,MyTask
将具有要像这样宣布:
execute()
否则你会有编译错误。
再次检查Android doc,以便稍微更广泛地使用这些类型参数。
答案 1 :(得分:0)
当用户“desseim”指出时,你只需要执行任务:
mt.execute();
execute方法的参数用于将数据传递给doInBackground()方法覆盖,可以使用“params”变量获取。如果您不需要在后台任务中操作或访问活动并且正在为任务使用单独的类文件,那么执行此操作对您来说不是必需的,并且非常有用。由于您的任务类位于Activity中,因此您可以直接访问Activity数据,因此通过execute传递参数毫无意义。