GCD是Grand Central Dispatch的简称,是建立在BSD层面上的接口,在Mac 10.6和iOS4.0之后才引入的。而且现在的NSOperation与NSoperationQueue的多线程实现就是基于GCD实现的。目前这个特性被移植到了FreeBSD上了,可以查看libdispatch这个开源项目。
在使用GCD 之前,先添加libsystem.dylib动态加载库,在头文件引入#import《dispatch/dispatch.h》,之后就可以程序中使用GCD了
下面以我的程序中的一个代码片段为例:
先创建线程实例:dispatch_queue_t network_queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
将需要处理大量数据,费时的代码放进次级线程
dispatch_async(network_queue, ^{
NSString *secondHtml=[[[NSString alloc]init]autorelease];
NSURL *url=[NSURL URLWithString:@"http://map.mapbar.com/"];
self.parseHtml=[[ParserHtml alloc]initWithHtml:url andTag:@"a"];
//得到对应城市名的第二个页面地址
secondHtml=[self.parseHtml ParserHtml];
NSString *text=[[[NSString alloc]init]autorelease];
text=[self.parseHtml ParseSecondHtml:[NSURL URLWithString:secondHtml] andTag:@"_3"];
NSLog(@"%@",text);
//返回主线程
dispatch_async(dispatch_get_main_queue(), ^{
//设置标题
jidiaoAppDelegate *single=[[UIApplication sharedApplication]delegate];
self.title=[single.cityName stringByAppendingString:@"历史"];
self.textView =[[UITextView alloc]initWithFrame:CGRectMake(10, 10, 300, 400)];
self.textView.text=text;
self.textView.delegate=self;
self.view.backgroundColor=[UIColor blueColor];
self.textView.textAlignment=UITextAlignmentLeft;
[self.view addSubview:self.textView];
});
});
以上内容是我的个人见解,由于刚刚接触到多线程,不免有很多瑕疵,以及术语的错误,还望多多指教。
更多内容,请访问:http://geeklu.com/2012/02/thread/
http://www.cnblogs.com/scorpiozj/archive/2011/07/25/2116459.html
如果需要查看两地之间所移动的路线图,就需要在地图上绘制线条和图标来查看了,废话不多说,贴上代码!
JAVA代码:
package com.SoAi.Activity;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
public class MainActivity extends MapActivity {
private GeoPoint point ;
private Projection projection;
private List<Overlay> overlays;
private GeoPoint beginGeoPoint = null;
private GeoPoint endGeoPoint= null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager locationManager = (LocationManager) MainActivity.this
.getSystemService(Context.LOCATION_SERVICE);
MapView mMapView = (MapView) findViewById(R.id.mapsView);
mMapView.setBuiltInZoomControls(true);//设置启用内置的缩放控件
// mMapView.setTraffic(true); //设置为交通模式。
// mMapView.setSatellite(true); //设置为卫星模式。
// mMapView.setStreetView(true); //设置为街道模式。
// 得到mMapView的控制权,可 以用它控制和驱动平移和缩放
MapController mMapController = mMapView.getController();
overlays = mMapView.getOverlays();
projection = mMapView.getProjection();
// 创建一个Criteria对象
Criteria criteria = new Criteria();
// 设置粗略精确度
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
// 设置是否需要返回海拔信息
criteria.setAltitudeRequired(false);
// 设置是否需要返回方位信息
criteria.setBearingRequired(false);
// 设置是否允许付费服务
criteria.setCostAllowed(true);
// 设置电量消耗等级
criteria.setPowerRequirement(Criteria.POWER_HIGH);
// 设置是否需要返回速度信息
criteria.setSpeedRequired(false);
// 根据设置的Criteria对象,获取最符合此标准的provider对象
String currentProvider = locationManager
.getBestProvider(criteria, true);
Location location = locationManager
.getLastKnownLocation(currentProvider);
// 参数1、location provider LocationManager.GPS_PROVIDER 2、最少多少毫秒更新一下定位,3、最短多少米更新一下位置,4、监听 事件
locationManager.requestLocationUpdates(
currentProvider, 6000, 500,
new TestLocationListener());
//point = new GeoPoint((int) (22.679836* 1000000), (int) (113.454567* 1000000));
point = new GeoPoint((int)(location.getLatitude()*1e6),(int)(location.getLongitude()*1e6));
mMapController.setCenter(point);
//mMapController.animateTo(point);
mMapController.setZoom(15);
//添加Overlay,用于显示标注信息
MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
overlays.add(myLocationOverlay);
}
//该类的对象用户在地图上绘制线条
class LineOverlay extends Overlay {
private GeoPoint begin;
private GeoPoint end;
public LineOverlay() {
}
public LineOverlay(GeoPoint begin, GeoPoint end) {
this.begin = begin;
this.end = end;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, shadow);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(2);
Point beginPoint = new Point();
Point endPoint = new Point();
Path path = new Path();
projection.toPixels(beginGeoPoint, beginPoint);
projection.toPixels(endGeoPoint, endPoint);
path.moveTo(endPoint.x, endPoint.y);
path.lineTo(beginPoint.x, beginPoint.y);
canvas.drawPath(path, paint);
}
}
//该类的对象的作用是在地图上绘制图标
class PointOverlay extends Overlay {
private GeoPoint geoPoint;
public PointOverlay() {
}
public PointOverlay(GeoPoint geoPoint) {
this.geoPoint = geoPoint;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, shadow);
Point point = new Point();
projection.toPixels(geoPoint, point);
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.icon_locr_light);
Paint paint = new Paint();
canvas.drawBitmap(bmp, point.x, point.y, paint);
}
}
//绘制定位图标
class MyLocationOverlay extends Overlay
{
@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
{
super.draw(canvas, mapView, shadow);
Paint paint = new Paint();
Point myScreenCoords = new Point();
// 将经纬度转换成实际屏幕坐标
projection.toPixels(point, myScreenCoords);
paint.setStrokeWidth(1);
paint.setARGB(255, 255, 0, 0);
paint.setStyle(Paint.Style.STROKE);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon_locr_light);
canvas.drawBitmap(bmp, myScreenCoords.x, myScreenCoords.y, paint);
//canvas.drawText("广州欢迎你", myScreenCoords.x, myScreenCoords.y, paint);
return true;
}
}
//监听事件,当移动超过指定的时间或距离调用
private class TestLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
if(endGeoPoint == null){
beginGeoPoint = point;
endGeoPoint = new GeoPoint((int)(location.getLatitude()*1e6),(int)(location.getLongitude()*1e6));
}else if(endGeoPoint !=null){
beginGeoPoint = endGeoPoint;
endGeoPoint = new GeoPoint((int)(location.getLatitude()*1e6),(int)(location.getLongitude()*1e6));
}
System.out.println(location.getLongitude());
System.out.println(location.getLatitude());
overlays.add(new PointOverlay(beginGeoPoint));
overlays.add(new PointOverlay(endGeoPoint));
overlays.add(new LineOverlay(beginGeoPoint, endGeoPoint));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.SoAi.Activity"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<!-- 联网 -->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<!-- 定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<uses-library android:name="com.google.android.maps"/>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>XML布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapsView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="0pbz1nfRMm_rQhNwDB4hE549_EJ86lD00BUyCNw"
android:enabled="true"
android:clickable="true"
/>
</LinearLayout>
好了,在模拟器里面查看只需要send一下它的经纬度,手机里就需要移动至少500M才行,OK!
Ant 是什么?
Apache Ant 是一个基于 Java 的生成工具。据最初的创始人 James Duncan Davidson 介绍,这个工具的名称是 another neat tool(另一个整洁的工具) 的首字母缩写。
Ant的作用:
生成工具在软件开发中用来将源代码和其他输入文件转换为可执行文件的形式(也有可能转换为可安装的产品映像形式)。随着应用程序的生成过程变得更加复杂,确保在每次生成期间都使用精确相同的生成步骤,同时实现尽可能多的自动化,以便及时产生一致的生成版本,这就变得更加重要.
Ant的优势:
Ant是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷。目前的最新版本为:Ant 1.8.4。 既然我们已经有了make, gnumake, nmake, jam以及其他的build工具为什么还要要一种新的build工具呢?因为Ant的原作者在多种(硬件)平台上开发软件时,无法忍受这些工具的限制和不便。类似于make的工具本质上是基于shell(语言)的:他们计算依赖关系,然后执行命令(这些命令与你在命令行敲的命令没太大区别)。这就意味着你可以很容易地通过使用OS特有的或编写新的(命令)程序扩展该工具;然而,这也意味着你将自己限制在了特定的OS,或特定的OS类型上,如Unix.
Ant就不同了。与基于shell命令的扩展模式不同,Ant用Java的类来扩展。(用户)不必编写shell命令,配置文件是基于XML的,通过调用target树,就可执行各种task。每个task由实现了一个特定Task接口的对象来运行。
Ant 定义生成文件之间的依赖关系,它使用跨平台的 Java 类。使用 Ant,您能够编写单个生成文件,这个生成文件在任何 Java 平台上都一致地操作(因为 Ant 本身也是使用 Java 语言来实现的),这就是 Ant 最大的优势
Ant生成文件剖析:
Ant 没有定义它自己的自定义语法;相反,它的生成文件是用 XML 编写的。存在一组 Ant 能够理解的预定义 XML 元素,而且还可以定义新的元素来扩展 Ant 的功能。每个生成文件由单个 project 元素组成,该元素又包含一个或多个 target 元素。一个目标(target)是生成过程中已定义的一个步骤,它执行任意数量的操作,比如编译一组源文件。并且这些操作本身是由其他专用任务标签执行的然后这些任务将根据需要被分组到各个 target 元素中。一次生成过程所必需的所有操作可以放入单个 target
元素中,但是那样会降低灵活性。将那些操作划分为逻辑生成步骤,每个步骤包含在它自己的 target 元素中,这样通常更为可取。这样可以执行整体生成过程的单独部分,却不一定要执行其他部分。
例如,通过仅调用某些目标,您可以编译项目的源代码,却不必创建可安装的项目文件
顶级 project 元素需要包含一个 default 属性,如果在 Ant 被调用时没有指定目标,这个属性将指定要执行的目标。然后需要使用 target 元素来定义该目标本身。
下面是一个最基本的生成文件:
<?xml version="1.0"?> <project default="init"> <target name="init"> </target> </project>
Ant基本使用方式:
1. 配置环境变量:
ANT_HOME: C:\ant-1.8 -----> Ant的安装/解压目录路径
PATH后追加: C:\ant-1.8\bin ------>Ant中的BIN目录路径
2. 确认环境变量配置是否成功
打开CMD窗口,然后输入命令: ant:
看到如下显示:
由于Ant构建时需要默认有build.xml文件,因此有如上的提示,至此,说明Ant的环境已经配置成功.
3. 使用Ant创建一个名为HelloWorld的文件夹:
首先需要编辑build.xml:
<?xml version="1.0"?>
<project default="init">
<target name="init">
<mkdir dir="HelloWorld">
</target>
</project>
然后切换到build.xml文件所在的目录,输入ant,若有如下提示,则创建文件夹成功:
(init 部分相当于 日志的输出)
4. 也可以使用ant创建多级嵌套的文件目录
只需要在build.xml文件中进行修改:
<?xml version="1.0"?>
<project default="init">
<target name="init">
<mkdir dir="HelloWorld\a\b\c"/>
</target>
</project>5. 删除如上的多级目录:
<?xml version="1.0"?>
<project default="init">
<target name="init">
<delete dir="HelloWorld"/>
</target>
</project>注意:此处路径只用输入最高级目录路径,这也正是ANT工具的强大之处:
Java中如果要删除目录,除非该目录为空才可以删除,否则就要逐步进行删除.
而使用Ant工具,则可以直接删除含有子目录的文件夹.