Да. Вы можете определенно посмотреть местоположение в фоновом режиме, если ваш мобильный браузер поддерживает Geolocation API
.
Вы можете использовать функцию
blockquote>watchPosition()
.watchPosition ( ) Code Snippet
var watchID = navigator.geolocation.watchPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
Если данные позиции изменяются (либо путем перемещения устройства, либо при получении более точной геоинформации), вы можете настроить функцию обратного вызова, вызываемую с этой обновленной информацией о местоположении , Это делается с помощью функции
blockquote>watchPosition()
, которая имеет те же входные параметры, что иgetCurrentPosition()
. Функция обратного вызова вызывается несколько раз, позволяя браузеру либо обновлять ваше местоположение при перемещении, либо предоставлять более точное местоположение.getCurrentPosition () Фрагмент кода
navigator.geolocation.getCurrentPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
Чтобы получить дополнительную информацию, обратитесь к Mozilla / Geolocation / WatchCurrentPosition
Надеюсь, что это поможет!
Нет другого способа сделать это, кроме того, что вы описали. Подумайте об этом - как кто-нибудь может узнать, какие классы расширяют ClassX без проверки каждого класса в пути к классам?
Eclipse может только рассказать вам о супер и подклассах в том, что кажется «эффективным» количеством времени, потому что он уже имеет все данные типа, загруженные в тот момент, когда вы нажимаете кнопку «Отображать в иерархии типов» (поскольку она постоянно компилирует ваши классы, знает обо всем на пути к классам и т. д.).
Следует также отметить, что это, конечно же, найдет только те подклассы, которые существуют в вашем текущем пути к классам. Предположительно, это нормально для того, что вы сейчас просматриваете, и, скорее всего, вы это рассмотрели, но если в какой-то момент вы выпустили класс не final
в дикий (для разных уровней «дикий»), то это вполне возможно, что кто-то еще написал свой собственный подкласс, о котором вы не узнаете.
Таким образом, если вам захотелось увидеть все подклассы, потому что вы хотите внести изменения и увидите, как это влияет поведение подклассов - тогда имейте в виду подклассы, которые вы не видите. В идеале все ваши не-частные методы и сам класс должны быть хорошо документированы; внесите изменения в соответствии с этой документацией, не изменяя семантику методов / нефизических полей, и ваши изменения должны быть обратно совместимы для любого подкласса, который по крайней мере соответствовал вашему определению суперкласса.
Я знаю, что на несколько лет опаздываю на эту вечеринку, но я столкнулся с этим вопросом, пытаясь решить ту же проблему. Вы можете использовать внутренний поиск Eclipse программно, если вы пишете плагин Eclipse (и, таким образом, используете их кеширование и т. Д.), Чтобы найти классы, которые реализуют интерфейс. Вот мой (очень грубый) первый снимок:
protected void listImplementingClasses( String iface ) throws CoreException
{
final IJavaProject project = <get your project here>;
try
{
final IType ifaceType = project.findType( iface );
final SearchPattern ifacePattern = SearchPattern.createPattern( ifaceType, IJavaSearchConstants.IMPLEMENTORS );
final IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
final SearchEngine searchEngine = new SearchEngine();
final LinkedList<SearchMatch> results = new LinkedList<SearchMatch>();
searchEngine.search( ifacePattern,
new SearchParticipant[]{ SearchEngine.getDefaultSearchParticipant() }, scope, new SearchRequestor() {
@Override
public void acceptSearchMatch( SearchMatch match ) throws CoreException
{
results.add( match );
}
}, new IProgressMonitor() {
@Override
public void beginTask( String name, int totalWork )
{
}
@Override
public void done()
{
System.out.println( results );
}
@Override
public void internalWorked( double work )
{
}
@Override
public boolean isCanceled()
{
return false;
}
@Override
public void setCanceled( boolean value )
{
}
@Override
public void setTaskName( String name )
{
}
@Override
public void subTask( String name )
{
}
@Override
public void worked( int work )
{
}
});
} catch( JavaModelException e )
{
e.printStackTrace();
}
}
Первой проблемой, которую я вижу до сих пор, является то, что я только улавливаю классы, которые непосредственно реализуют интерфейс, а не все их подклассы - но небольшая рекурсия никогда больно кому угодно.
Мне нужно было сделать это в качестве тестового примера, чтобы узнать, добавлены ли новые классы в код. Это то, что я сделал
final static File rootFolder = new File(SuperClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
private static ArrayList<String> files = new ArrayList<String>();
listFilesForFolder(rootFolder);
@Test(timeout = 1000)
public void testNumberOfSubclasses(){
ArrayList<String> listSubclasses = new ArrayList<>(files);
listSubclasses.removeIf(s -> !s.contains("Superclass.class"));
for(String subclass : listSubclasses){
System.out.println(subclass);
}
assertTrue("You did not create a new subclass!", listSubclasses.size() >1);
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
files.add(fileEntry.getName().toString());
}
}
}
Я сделал это несколько лет назад. Самый надежный способ сделать это (например, с официальными API Java и без внешних зависимостей) - написать пользовательский документ, чтобы создать список, который можно прочитать во время выполнения.
Вы можете запустить его из командной строки например:
javadoc -d build -doclet com.example.ObjectListDoclet -sourcepath java/src -subpackages com.example
или запустить его из муравья вроде этого:
<javadoc sourcepath="${src}" packagenames="*" >
<doclet name="com.example.ObjectListDoclet" path="${build}"/>
</javadoc>
Вот базовый код:
public final class ObjectListDoclet {
public static final String TOP_CLASS_NAME = "com.example.MyClass";
/** Doclet entry point. */
public static boolean start(RootDoc root) throws Exception {
try {
ClassDoc topClassDoc = root.classNamed(TOP_CLASS_NAME);
for (ClassDoc classDoc : root.classes()) {
if (classDoc.subclassOf(topClassDoc)) {
System.out.println(classDoc);
}
}
return true;
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
}
Для простоты I 'удалил синтаксический анализ аргумента командной строки, и я пишу в System.out вместо файла.
Сканирование для классов непросто с чистой Java.
Spring framework предлагает класс под названием ClassPathScanningCandidateComponentProvider , который может делать то, что вам нужно. В следующем примере будут найдены все подклассы MyClass в пакете org.example.package
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(MyClass.class));
// scan in org.example.package
Set<BeanDefinition> components = provider.findCandidateComponents("org/example/package");
for (BeanDefinition component : components)
{
Class cls = Class.forName(component.getBeanClassName());
// use class cls found
}
Этот метод имеет дополнительное преимущество использования анализатора байт-кода для поиска кандидатов, что означает, что он будет не загружает все классы, которые он сканирует.
Я использую отражение lib, которое сканирует ваш путь к классам для всех подклассов: https://github.com/ronmamo/reflections
Вот как это было бы сделано:
Reflections reflections = new Reflections("my.project");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Попробуйте ClassGraph . (Отказ от ответственности, я автор). ClassGraph поддерживает сканирование для подклассов данного класса либо во время выполнения, либо во время сборки, но и многое другое. ClassGraph может создавать абстрактное представление всего графа классов (все классы, аннотации, методы, параметры метода и поля) в памяти, для всех классов в пути к классам или для классов в белых списках, и вы можете запросить этот графа классов, однако вы хотите. ClassGraph поддерживает больше механизмов спецификации классов и загрузчиков классов , чем любой другой сканер, а также легко работает с новой системой модулей JPMS, поэтому, если вы основываете свой код на ClassGraph, ваш код будет максимально переносимым. См. здесь API.
В зависимости от ваших конкретных требований, в некоторых случаях механизм загрузки Java службы может достичь того, что вы после.
. Короче говоря, он позволяет разработчикам явно объявлять, что класс подклассы другого класса (или реализует некоторый интерфейс), перечислив его в файле в каталоге META-INF/services
файла JAR / WAR. Затем он может быть обнаружен с использованием класса java.util.ServiceLoader
, который при заданном объекте Class
будет генерировать экземпляры всех объявленных подклассов этого класса (или, если Class
представляет собой интерфейс , все классы, реализующие этот интерфейс).
Основное преимущество этого подхода состоит в том, что нет необходимости вручную сканировать весь путь к классам для подклассов - вся логика обнаружения содержится в классе ServiceLoader
и он загружает классы, явно объявленные в каталоге META-INF/services
(не каждый класс в пути к классам).
Однако есть некоторые недостатки:
META-INF/services
. Это дополнительное бремя для разработчика и может быть подвержено ошибкам. ServiceLoader.iterator()
генерирует экземпляры подкласса, а не их Class
объектов. Это вызывает две проблемы: вы не можете сказать, как строятся подклассы - конструктор no-arg используется для создания экземпляров. Таким образом, подклассы должны иметь конструктор по умолчанию или должны быть объяснены конструктором no-arg. Очевидно, что Java 9 будет решать некоторые из этих недостатков (в частности, те, которые касаются создания подклассов).
Предположим, вам интересно найти классы, реализующие интерфейс com.example.Example
:
package com.example;
public interface Example {
public String getStr();
}
Класс com.example.ExampleImpl
реализует этот интерфейс:
package com.example;
public class ExampleImpl implements Example {
public String getStr() {
return "ExampleImpl's string.";
}
}
Вы объявили бы класс ExampleImpl
представляет собой реализацию Example
путем создания файла META-INF/services/com.example.Example
, содержащего текст com.example.ExampleImpl
.
Затем вы можете получить экземпляр каждой реализации Example
(включая экземпляр ExampleImpl
) следующим образом:
ServiceLoader<Example> loader = ServiceLoader.load(Example.class)
for (Example example : loader) {
System.out.println(example.getStr());
}
// Prints "ExampleImpl's string.", plus whatever is returned
// by other declared implementations of com.example.Example.
Это невозможно сделать, используя только встроенный API Java Reflections.
Существует проект, который выполняет необходимое сканирование и индексирование вашего пути к классам, чтобы вы могли получить доступ к этой информации ...
Анализ метаданных во время выполнения Java в духе Scannotations
Отражения сканируют ваш путь к классам , индексирует метаданные, позволяет запрашивать его во время выполнения и может сохранять и собирать эту информацию для многих модулей вашего проекта.Используя Reflections, вы можете запросить свои метаданные для:
blockquote>
- получить все подтипы некоторого типа
- получить все типы, аннотированные с некоторой аннотацией
- get все типы, аннотированные некоторой аннотацией, включая параметры аннотации, соответствующие
- , получают все методы, аннотированные некоторыми
(отказ от ответственности: я не использовал его, но описание проекта, по-видимому, точно соответствует вашим потребностям.)
Имея в виду ограничения, упомянутые в других ответах, вы также можете использовать openpojo's PojoClassFactory
(, доступный на Maven ) следующим образом:
for(PojoClass pojoClass : PojoClassFactory.enumerateClassesByExtendingType(packageRoot, Superclass.class, null)) {
System.out.println(pojoClass.getClazz());
}
Где packageRoot
- это корневая строка пакетов, которые вы хотите искать (например, "com.mycompany"
или даже просто "com"
), а Superclass
- ваш супертип (это также работает и с интерфейсами) .
Причина, по которой вы видите разницу между вашей реализацией и Eclipse, заключается в том, что вы просматриваете каждый раз, в то время как Eclipse (и другие инструменты) сканируют только один раз (во время загрузки проекта большую часть времени) и создают индекс. В следующий раз, когда вы попросите данные, которые он не сканирует снова, но посмотрите на индекс.
Добавьте их в статическую карту внутри (this.getClass (). getName ()) конструктор родительских классов (или создайте по умолчанию), но это будет обновляться во время выполнения. Если ленивая инициализация - это вариант, вы можете попробовать этот подход.
Не забывайте, что сгенерированный Javadoc для класса будет включать список известных подклассов (и для интерфейсов, известных классов реализации).
Я просто написал простое демо, чтобы использовать org.reflections.Reflections
для получения подклассов абстрактного класса:
reflections.getSubTypesOf(aClazz))
– Enwired 20 February 2015 в 02:29