接口的使用,以及在异步任务中的使用

相信很多java和Android初学者,都对接口的定义有一些了解,但是如何使用它,利用它的特性来更好的实现自己想要的功能,却不甚了解。之前,我写代码也是没怎么用过接口,看到Android里,如监听方法里实现接口的写法,如:setOnClickListener(new
OnClickListener(),或者网络请求的回调方法等等。都用到接口,实现了回调方法。这样写的好处,试过了就知道了。

好处一:在你想要实现某种功能(却还不明确具体需求)的地方,你只需要在哪里调用 接口的抽象方法,而具体的实现,你却可以在你喜欢的其他地方实现。

例如:监听方法的onclick回调方法,它里面的代码执行在点击事件完成后。仿写一个:

//接口的定义
public interface Callbackinterface {
	void dosomethinFailed();
	void dosomethingSuceess();
}
<pre name="code" class="java">//接口的抽象方法调用的地方,这个例子里在Bijiao类里的方法里通过判断调用
public class Bijiao{

	public  void comprate(int a,int b,Callbackinterface callbackinterface){
		if (a>b) {
			callbackinterface.dosomethingSuceess();
		}else {
			callbackinterface.dosomethinFailed();
		}
	}
}

<pre name="code" class="java">//最后,在java的mian方法里,调用Bijiao类的方法,并传入一个实现的接口,就可以了,重写的方法调用在上面的判断里,并执行
public class Test {
	public static void main(String[] args) {
		Bijiao bijiao=new Bijiao();
		bijiao.comprate(5, 4, new Callbackinterface() {

			@Override
			public void dosomethingSuceess() {
				// TODO Auto-generated method stub
				//dosomething you want
			}

			@Override
			public void dosomethinFailed() {
				// TODO Auto-generated method stub
				//dosomething you want
			}
		});

	}

<p>}</p>

显然,通过接口你可以在回调方法里做你想做的事,而不用接口的话,你可能会将Bijiao类的的方法的代码写死,不便于复用和修改。面向接口编程,也是一种解耦的不错选择。接下来,我们来做一个稍微复杂点的案例。我们的项目里,总是会遇到很多异步处理的需求,多线程来处理这些任务。通常,我们会用thread和handler,或者异步任务来做这些事情。异步任务和handler就挑异步任务来说下吧,因为异步任务本身也就是将thread和handler处理封装了而已,而且,也用的是接口。在异步任务AsyncTask里,有两个重要的重写方法doInBackground和onPostExecute,分别就是工作线程和ui线程的操作了。

接下来,我想将异步任务进一步通过实现一个接口,来使得这个异步任务类跟适合复用。

//先定义一个接口,这个接口用来实现工作线程的执行代码
public interface BackgroundInit {
	boolean doinbackground();

}
//在定义一个接口,执行UI线程要执行的代码
public interface UiExecute {
	void onsucess();
	void onfailed();
}
//定义一个继承AsyncTask的类
public class XpAsynncTask extends AsyncTask<Void, Void, Boolean>{
	UiExecute execute;
	BackgroundInit init;
	//构造方法传入这两个接口的实现类
	public XpAsynncTask(UiExecute execute,BackgroundInit init){
		this.execute=execute;
		this.init=init;
	}
	@Override
	protected Boolean doInBackground(Void... params) {
		// TODO Auto-generated method stub
		boolean result=false;
		result=init.doinbackground();//接口的抽象方法,具体实现在调用这个类的构造方法前实现
		return result;
	}

	@Override
	protected void onPostExecute(Boolean result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		if (result) {
			execute.onsucess();//接口的抽象方法,具体实现在调用这个类的构造方法前实现
		}else {
			execute.onfailed();//接口的抽象方法,具体实现在调用这个类的构造方法前实现
		}
	}

}

最后,在你要调用这个异步任务处理的时候,你只需要如下,就不用每次都重写一个异步任务去修改doInBackground和onPostExecute里的代码了。

<pre name="code" class="html">XpAsynncTask task=new XpAsynncTask(new UiExecute() {

				@Override
				public void onsucess() {
					// TODO Auto-generated method stub

				}

				@Override
				public void onfailed() {
					// TODO Auto-generated method stub

				}
			}, new BackgroundInit() {

				@Override
				public boolean doinbackground() {
					// TODO Auto-generated method stub
					return false;
				}
			});
			task.execute();

同样的,你还可以继续在这个代码块的某个地方再实现个接口,暴露给调用者实现的接口就当做方法的参数即可。就像我上面的写法,就是给异步任务嵌套了一层接口而已。

public void writeDataByYouself(UiExecute execute,
				final ProcessData processData) {//processData,再次增加的一个接口,这个接口只让调用者添加数据,发送的事情,我来做
			// TODO Auto-generated method stub
			XpAsynncTask task=new XpAsynncTask(execute,new BackgroundInit() {//BackgroundInit接口我不暴露给调用者去实现了

				@Override
				public boolean doinbackground() {
					// TODO Auto-generated method stub

					List<byte[]> list=processData.processDataBeforeSend();//processData,再次增加的一个接口,这个接口只让调用者添加数据,发送的事情,我来做
					if (list!=null) {
						for (int i = 0; i < list.size(); i++) {

							mMsg=xPrinterDev.Write(list.get(i));
						}
						if (mMsg.GetErrorCode().equals(ErrorCode.WriteDataSuccess)) {
							return true;
						}
					}
					return false;
				}
			});
			//task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			task.execute();
		}
</pre><pre>

恩,看了这几个例子,你是不是发现,接口其实没什么,就是在另外一个方法里,参数是这个接口的实现类,然后在方法体的某一个地方调用它的抽象方法吧了,说的简单点,就是把一个代码块换到了你想执行的地方去执行,而那个执行的地方用接口的抽象方法做了标记。没错,就是这么简单。

还有一点好处就是,如果你的异步任务的子类,不是写着Activity或者fragment里的话,又想进行一些ui操作,怎么办,难道把要进行ui操作的控件和对象全部通过构造方法传参过去?还是是个控件对象你就定义为静态的?这样肯定不怎么好吧。那就用接口吧,在活动或者碎片里,实现接口,就很容易解决这些问题。而这个异步任务的子类也将具有非常高的复用性。代码结构也简洁易懂。

这一篇就说那么多了,下一篇,讲下接口,service,异步任务的结合使用情况。不忙的话。

时间: 2024-10-10 00:32:29

接口的使用,以及在异步任务中的使用的相关文章

Async/Await 异步编程中的最佳做法

近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的“第二步”:我假设您已阅读过有关这一方面的至少一篇介绍性文章. 本文不提供任何新内容,Stack Overflow.MSDN 论坛和 async/await FAQ 这类在线资源提供了同样的建议. 本文只重点介绍一些淹没在文档海洋中的最佳做法. 本文中的最佳做法更大程度上是“指导原则”,而不是实际规则. 其中每个指导原则都有一些例外情况

异步编程中的最佳做法

原文链接 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的“第二步”:我假设您已阅读过有关这一方面的至少一篇介绍性文章. 本文不提供任何新内容,Stack Overflow.MSDN 论坛和 async/await FAQ 这类在线资源提供了同样的建议. 本文只重点介绍一些淹没在文档海洋中的最佳做法. 本文中的最佳做法更大程度上是“指导原则”,而不是实际规则. 其中每个指导原则都有一

异步编程中的最佳做法(Async/Await) --转

近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支持的信息. 本文旨在作为学习异步编程的“第二步”:我假设您已阅读过有关这一方面的至少一篇介绍性文章. 本文不提供任何新内容,Stack Overflow.MSDN 论坛和 async/await FAQ 这类在线资源提供了同样的建议. 本文只重点介绍一些淹没在文档海洋中的最佳做法. 本文中的最佳做法更大程度上是“指导原则”,而不是实际规则. 其中每个指导原则都有一些例外情况

如何在Spring异步调用中传递上下文

以下文章来源于aoho求索 ,作者aoho 1. 什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行.异步调用指,在程序在执行时,无需等待执行的返回值即可继续执行后面的代码.在我们的应用服务中,有很多业务逻辑的执行操作不需要同步返回(如发送邮件.冗余数据表等),只需要异步执行即可. 本文将介绍 Spring 应用中,如何实现异步调用.在异步调用的过程中,会出现线程上下文信息的丢失

Effective JavaScript Item 63 注意异步调用中可能会被忽略的异常

异常处理是异步编程的一个难点. 在同步的代码中,异常可以非常easy地通过try catch语句来完毕: try { f(); g(); h(); } catch (e) { // handle any error that occurred... } 可是在异步代码中,使用一个try代码块将全部可能出现的异常都包含在内是不现实的.实际上,异步API设置不能抛出异常.由于当异常发生时,通常已经没有运行上下文供它抛出了. 全部,在异步API中一般会使用特殊的參数或者错误回调函数来表示异常信息.比方

被动接口在rip,eigrp,ospf中的应用

被动接口的概念是:阻止从该接口发送路由更新.除了BGP之外的所有基于IP路由协议都可以使用被动接口, 一.在RIP中使用被动接口 1.使用被动接口的目的在某些网络环境中,我们不希望将RIP更新发送给某些路由器或者说发送到某个网络中去,我们就可以使用passive-interface这个命令阻止RIP更新广播从指定接口发送到外界,但是这一接口任然可以接受RIP更新 2.passive-interface的原理 应用了passive-interface的接口,也就是被动接口,是不能够发送广播和组播的

你不知道的this—JS异步编程中的this

Javascript小学生都知道了javascript中的函数调用时会 隐性的接收两个附加的参数:this和arguments.参数this在javascript编程中占据中非常重要的地位,它的值取决于调用的模式.总的来说Javascript中函数一共有4中调用模式:方法调用模式.普通函数调用模式.构造器调用模式.apply/call调用模式.这些模式在如何初始化关键参数this上存在差异.“可能还有小伙伴不知道它们之间的区别,那我就勉为其难撸一撸吧!” 方法调用模式:函数是在某个明确的上下文对

[Effective JavaScript 笔记]第62条:在异步序列中使用嵌套或命名的回调函数

异步程序的操作顺序 61条讲述了异步API如何执行潜在的代价高昂的I/O操作,而不阻塞应用程序继续处理其他输入.理解异步程序的操作顺序刚开始有点混乱.例如,下面的代码会在打印"finished"之前打印"starting",即使这两个动作的程序源文件中以相反的顺序呈现. downloadAsync('file.txt',function(file){ console.log('finished'); }); console.log('starting'); down

HttpContext在多线程异步调用中的使用方案

1.在线程调用中,有时候会碰到操作文件之类的功能.对于开发人员来说,他们并不知道网站会被部署在服务器的那个角落里面,因此根本无法确定真实的物理路径(当然可以使用配置文件来配置物理路径),他们唯一知道的就是文件在项目中的相对路径,为了定位文件路径,一般都会调用HttpContext.Current.Request.MapPath或者HttpContext.Current.Server.MapPath,但是在多线程调用中,HttpContext肯定为null,这时候还调用MapPath结果就是报错.