• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

Bukkit/插件开发教程/定时器编程:修订间差异

来自Minecraft插件百科
跳转到导航 跳转到搜索
(创建)
 
 
(未显示2个用户的3个中间版本)
第10行: 第10行:


= BukkitRunnable =
= BukkitRunnable =
[http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable] is an abstract implementation of [http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/Runnable.html Runnable]. It also supports additional operations that a Runnable is not capable of, most conveniently, BukkitRunnables can schedule and cancel their own execution. However, if the BukkitRunnable did not schedule itself for execution, it cannot cancel itself from execution. BukkitRunnables are not schedulers, do not contain any scheduler logic, and are not expensive to create. Plugins should prefer defining a BukkitRunnable and calling the appropriate run method over directly scheduling a Runnable with the BukkitScheduler.
[http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable] 实现了[http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/Runnable.html Runnable] 的抽象. 它还提供一个Runnable没有的功能, BukkitRunnables 可以安排和取消他自己的执行. 然而, 如果BukkitRunnables 没有被安排执行, 它也不能取消运行自身. BukkitRunnables 不是定时器, 没有任何定时器的逻辑功能,而且创建并不复杂. 插件应该更常使用BukkitRunnables 并且直接调用run()方法来直接调用 Runnable BukkitScheduler.


: ''For more information on BukkitRunnable, see the [http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable JavaDocs]''
: ''更多关于 BukkitRunnable 的信息, 请查看 [http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable JavaDocs]''


== Defining work ==
== 定义工作 ==
Plugins should first [http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html extend] [http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable] to define work that needs to be done. In other words, the definition of the run method is what you want executed in accordance to a schedule.
插件首先得完成t [http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html extend] [http://jd.bukkit.org/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html BukkitRunnable] 的定义工作. 换句话说, 定义一个你想要定时执行的运行方法.


=== Basic Example ===
=== 基本例子 ===
This is an example definition of a task that can be scheduled.
这是可被定时的任务示例.
<blockquote><source lang=java>import org.bukkit.Bukkit;
<blockquote><source lang=java>import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPlugin;
第33行: 第33行:
     @Override
     @Override
     public void run() {
     public void run() {
         // What you want to schedule goes here
         // 你需要在运行的时候执行的内容放这
         plugin.getServer().broadcastMessage("Welcome to Bukkit! Remember to read the documentation!");
         plugin.getServer().broadcastMessage("Welcome to Bukkit! Remember to read the documentation!");
     }
     }
第39行: 第39行:
}</source></blockquote>
}</source></blockquote>


=== Self-Canceling Example ===
=== 自我取消例子 ===
This is an example of a definition of a task that will cancel itself when it has executed the specified number of times
这是一个运行数次后自我取消的例子
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitRunnable;
第61行: 第61行:
     @Override
     @Override
     public void run() {
     public void run() {
         // What you want to schedule goes here
         // 你需要在运行的时候执行的内容放这
         if (counter > 0) {  
         if (counter > 0) {  
             plugin.getServer().broadcastMessage("Commence greeting in " + counter--);
             plugin.getServer().broadcastMessage("Commence greeting in " + counter--);
第72行: 第72行:
}</source></blockquote>
}</source></blockquote>


== Scheduling Work ==
== 定时任务 ==
After defining the task, the plugin needs to schedule the task. BukkitRunnables are scheduled when the desired run method is invoked on an instance of the task. The list of methods for BukkitRunnable can be found in the [http://jd.bukkit.org/rb/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html Javadocs for BukkitRunnable]. The different run methods all return a [[#BukkitTask | BukkitTask]] object
在完成定义工作后, 插件需要定时这个BukkitRunnable. BukkitRunnables 将被定时执行run()方法. BukkitRunnable 的方法列表能在这找到:[http://jd.bukkit.org/rb/apidocs/index.html?org/bukkit/scheduler/BukkitRunnable.html Javadocs for BukkitRunnable]. 所有的run方法都将返回[[#BukkitTask | BukkitTask]] 对象


{{warning| Asynchronous tasks should never access any API in Bukkit}}
{{warning| Asynchronous tasks should never access any API in Bukkit}}


=== Example ===
=== 例子 ===
This is an example of a plugin which registers a listener and when a player joins, schedules a task to be run 20 ticks later.  
这是一个注册了PlayerJoinEvent监听器的插件, 定时任务将在玩家加入游戏后20tick执行.  
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.Listener;
第105行: 第105行:
     @EventHandler
     @EventHandler
     public void onJoin(PlayerJoinEvent event) {
     public void onJoin(PlayerJoinEvent event) {
         // Create the task and schedule to run it once, after 20 ticks
         // 创建一个20tick后仅执行一次的任务
         BukkitTask task = new ExampleTask(this.plugin).runTaskLater(this.plugin, 20);
         BukkitTask task = new ExampleTask(this.plugin).runTaskLater(this.plugin, 20);
     }
     }
第112行: 第112行:
</source></blockquote>
</source></blockquote>


=== Self-Canceling Example ===
=== 自我取消例子 ===
This is example takes the above ExampleSelfCancelingTask and scheules it to run every 20 ticks after waiting 10 ticks.
这是采用之前提到的 ExampleSelfCancelingTask 定时为20tick延迟后执行 每10tick执行一次.
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.Listener;
第140行: 第140行:
     @EventHandler
     @EventHandler
     public void onJoin(PlayerJoinEvent event) {
     public void onJoin(PlayerJoinEvent event) {
         // Create the task and schedule
         // 创建定时任务
         BukkitTask task = new ExampleSelfCancelingTask(this.plugin, 5).runTaskTimer(this.plugin, 10, 20);
         BukkitTask task = new ExampleSelfCancelingTask(this.plugin, 5).runTaskTimer(this.plugin, 10, 20);
     }
     }
第147行: 第147行:
</source></blockquote>
</source></blockquote>


=== Anonymous BukkitRunnable Example ===
=== 匿名 BukkitRunnable 例子 ===
An anonymous BukkitRunnable will allow you to schedule a task, without creating a new class with a name. This examples combines the above two basic examples.
一个匿名的 BukkitRunnable 允许你安排一个任务,而不用创建一个带有名字的新类。这个例子结合了以上两个基本例子。
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
<blockquote><source lang="java">import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.Listener;
第175行: 第175行:
     @EventHandler
     @EventHandler
     public void onJoin(PlayerJoinEvent event) {
     public void onJoin(PlayerJoinEvent event) {
         // Create the task anonymously and schedule to run it once, after 20 ticks
         // 创建一个20tick执行的匿名任务
         new BukkitRunnable() {
         new BukkitRunnable() {
          
          
             @Override
             @Override
             public void run() {
             public void run() {
                 // What you want to schedule goes here
                 // 你想在这里安排什么
                 plugin.getServer().broadcastMessage(
                 plugin.getServer().broadcastMessage(
                     "Welcome to Bukkit! Remember to read the documentation!");
                     "Welcome to Bukkit! Remember to read the documentation!");

2018年6月27日 (三) 01:04的最新版本

This tutorial will guide you in using the scheduler provided by bukkit. It will allow you to defer the execution of code to a later time. This is not the same as registering a Listener, a block of code which is executed in response to an event in the game. Blocks of code may also be scheduled to be executed repeatedly at a fixed interval, with or without a delay. They will continue to execute until completed, or canceled, or your plugin is disabled.

When using BukkitRunnable, with a separate class, scheduling work occurs in two steps for the programmer.

  1. Define the work to be done, see the section Defining Work
  2. Notify Bukkit when the work should be executed, see the section Scheduling Work

Alternatively, work can be scheduled directly with the scheduler, this also occurs in two steps for the programmer.

  1. Define the work to be done, in a Runnable or Callable
  2. Then directly scheduling the work with the Bukkit Scheduler, see the section BukkitScheduler

BukkitRunnable

BukkitRunnable 实现了Runnable 的抽象. 它还提供一个Runnable没有的功能, BukkitRunnables 可以安排和取消他自己的执行. 然而, 如果BukkitRunnables 没有被安排执行, 它也不能取消运行自身. BukkitRunnables 不是定时器, 没有任何定时器的逻辑功能,而且创建并不复杂. 插件应该更常使用BukkitRunnables 并且直接调用run()方法来直接调用 Runnable 和 BukkitScheduler.

更多关于 BukkitRunnable 的信息, 请查看 BukkitRunnable JavaDocs

定义工作

插件首先得完成t extend BukkitRunnable 的定义工作. 换句话说, 定义一个你想要定时执行的运行方法.

基本例子

这是可被定时的任务示例.

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class ExampleTask extends BukkitRunnable {

    private final JavaPlugin plugin;

    public ExampleTask(JavaPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public void run() {
        // 你需要在运行的时候执行的内容放这
        plugin.getServer().broadcastMessage("Welcome to Bukkit! Remember to read the documentation!");
    }

}

自我取消例子

这是一个运行数次后自我取消的例子

import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

public class ExampleSelfCancelingTask extends BukkitRunnable {

    private final JavaPlugin plugin;
    
    private int counter;

    public ExampleSelfCancelingTask(JavaPlugin plugin, int counter) {
        this.plugin = plugin;
        if (counter < 1) {
            throw new IllegalArgumentException("counter must be greater than 1");
        } else {
            this.counter = counter;
        }
    }

    @Override
    public void run() {
        // 你需要在运行的时候执行的内容放这
        if (counter > 0) { 
            plugin.getServer().broadcastMessage("Commence greeting in " + counter--);
        } else {
            plugin.getServer().broadcastMessage("Welcome to Bukkit! Remember to read the documentation!");
            this.cancel();
        }
    }

}

定时任务

在完成定义工作后, 插件需要定时这个BukkitRunnable. BukkitRunnables 将被定时执行run()方法. BukkitRunnable 的方法列表能在这找到:Javadocs for BukkitRunnable. 所有的run方法都将返回 BukkitTask 对象

Asynchronous tasks should never access any API in Bukkit

例子

这是一个注册了PlayerJoinEvent监听器的插件, 定时任务将在玩家加入游戏后20tick执行.

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

public final class ExamplePlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        new ExampleListener(this);
    }
}

class ExampleListener implements Listener {

    private final ExamplePlugin plugin;

    public ExampleListener(ExamplePlugin plugin) {
        this.plugin = plugin;
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        // 创建一个20tick后仅执行一次的任务
        BukkitTask task = new ExampleTask(this.plugin).runTaskLater(this.plugin, 20);
    }

}

自我取消例子

这是采用之前提到的 ExampleSelfCancelingTask 定时为20tick延迟后执行 每10tick执行一次.

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

public final class ExamplePlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        new ExampleListener(this);
    }
}

class ExampleListener implements Listener {

    private final ExamplePlugin plugin;

    public ExampleListener(ExamplePlugin plugin) {
        this.plugin = plugin;
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        // 创建定时任务
        BukkitTask task = new ExampleSelfCancelingTask(this.plugin, 5).runTaskTimer(this.plugin, 10, 20);
    }

}

匿名 BukkitRunnable 例子

一个匿名的 BukkitRunnable 允许你安排一个任务,而不用创建一个带有名字的新类。这个例子结合了以上两个基本例子。

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

public final class ExamplePlugin extends JavaPlugin {
 
    @Override
    public void onEnable() {
        new ExampleListener(this);
    }
}
 
class ExampleListener implements Listener {
 
    private final ExamplePlugin plugin;
 
    public ExampleListener(ExamplePlugin plugin) {
        this.plugin = plugin;
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }
 
    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        // 创建一个20tick执行的匿名任务
        new BukkitRunnable() {
        
            @Override
            public void run() {
                // 你想在这里安排什么
                plugin.getServer().broadcastMessage(
                    "Welcome to Bukkit! Remember to read the documentation!");
            }
            
        }.runTaskLater(this.plugin, 20);
    }
 
}

BukkitScheduler

The BukkitScheduler allows plugins to schedule a Runnable and/or a Callable , for execution at a later time. The list of methods for BukkitScheduler can be found in the Javadocs for BukkitScheduler.

文件:Lightbulb.png Note: Plugins should not schedule a BukkitRunnable with the scheduler, instead they should run the BukkitRunnable with the desired schedule.

Example

Example for directly scheduling an anonymous Runnable with the BukkitScheduler to run after 20 ticks.

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;

public final class ExamplePlugin extends JavaPlugin {
    public void onEnable() {
        BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
        scheduler.scheduleSyncDelayedTask(this, new Runnable() {
            @Override
            public void run() {
                // Do something
            }
        }, 20L);
    }
}

Repeating Example

Example for directly scheduling an anonymous Runnable with the BukkitScheduler to run every twenty ticks, forever, starting from when you schedule it.

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;

public final class ExamplePlugin extends JavaPlugin {
    public void onEnable() {
        BukkitScheduler scheduler = Bukkit.getServer().getScheduler();
        scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
            @Override
            public void run() {
                // Do something
            }
        }, 0L, 20L);
    }
}

Asynchronous tasks should never access any API in Bukkit

BukkitTask

A BukkitTask object is returned whenever a Runnable is scheduled. This object represents the task the scheduled task being executed by the scheduler. For more information see, Javadocs for BukkitTask.

Callable and Future

A Callable given to the scheduler to call synchronously returns a Future. These are standard Java classes, for more information see, Javadocs for Callable and Javadocs for Future

Tips for thread safety

The Bukkit API, with the exception of the scheduler package, is not thread safe nor guaranteed to be thread safe.

  1. Asynchronous tasks should never access any API in Bukkit.
  2. Do not access or modify shared collections from your asynchronous tasks. Normal collections are not thread-safe. This also applies to objects which are not thread safe.
  3. An asynchronous task can schedule a synchronous task.
  4. A synchronous task can schedule an asynchronous task.
Language   中文English日本語