`
lizhensan
  • 浏览: 376852 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

eclipse 源码泛读

 
阅读更多

eclipse的入口插件:

org.eclipse.platform  

产品的定义,用到的图标,外观的定义都在这里,plugin.xml绑定一个application

这里没有代码,只是样式、图标。

org.eclipse.ui.ide.application

该插件是eclipse的真正入口,

主要的类有:

IDEApplication.java    IDEWorkbenchAdvisor.java   IDEWorkbenchWindowAdvisor.java 

ResourcePerspective.java  

这几个类大家应该都很属性。

不过没有ActionBarAdvisor的定义,说明eclipse中所有的菜单、工具栏,在启动的时候是为空的。

里面的菜单都是其它插件扩展得到的。

 

接下来进入org.eclipse.core.runtime  看看。

 

这里主要用到了  osgi  equinox    java.io  java.net  

 

Platform  对该类进行了包装  InternalPlatform      

InternalPlatform    中使用了个单利模式。

eclipse 也大量运用了单利模式。

 

public IAdapterManager getAdapterManager() {

assertInitialized();

return AdapterManager.getDefault();

}

 

查看代码可知  如何名称相同的bundle 会返回第一个被加载的bundle。

 

public Bundle getBundle(String symbolicName) {

PackageAdmin packageAdmin = getBundleAdmin();

if (packageAdmin == null)

return null;

Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);

if (bundles == null)

return null;

//Return the first bundle that is not installed or uninstalled

for (int i = 0; i < bundles.length; i++) {

if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {

return bundles[i];

}

}

return null;

}

 

 

该插件也相当于eclipse的 发动机了,服务的启动、停止、文件的加载等,都是在这里处理的。

 

 

下了看一下   org.eclipse.ui  插件。

该插件有点出乎意料

只有两个类UIPlugin   UIPreferenceInitializer

 

UIPlugin   中用到了  PrefUtil  这个类是对preferences操作的一个工具类,用着还是很方便的。

PrefUtil .getInternalPreferenceStore(); 直接得到 系统 IPreferenceStore

 

UIPreferenceInitializer 为eclipse  初始化一些参数,它是在这里定义的。

 

   <extension

         point="org.eclipse.core.runtime.preferences">

      <initializer

            class="org.eclipse.ui.internal.UIPreferenceInitializer">

      </initializer>

   </extension>

使用的是该org.eclipse.core.runtime.preferences扩展点,这个扩展点 在eclipse中用的还是很广的。

 

这个插件没有别的类了,剩下的就是一些扩展点的定义,并实现了一下扩展。

这里定义的都是系统最基础的扩展点,并初步实现了最基础的扩展。

 

 

 

org.eclipse.ui 插件的扩展点的定义、扩展 实现是通过那个插件实现的。

 

就拿org.eclipse.ui.views这个扩展点来说。

该扩展点依赖的类为 ViewPart,该类是在org.eclipse.ui.workbench  插件中定义的。

org.eclipse.ui.part包下。

查看ViewPart 源码有它实现了 

 

 

    protected final void checkSite(IWorkbenchPartSite site) {

        super.checkSite(site);

        Assert.isTrue(site instanceof IViewSite, "The site for a view must be an IViewSite");  

    }    

这里说明 Viewpart中的 site一定是  ViewSite

 

    public Object getAdapter(Class adapter) {

        return Platform.getAdapterManager().getAdapter(this, adapter);

    }

说明viewpart  是一个平台对象,可以通过adapter 扩展点进行适配。

 

实现了IExecutableExtension接口

说明它可以直接得到 扩展 中定义的  内容。

 

实现了EventManager 接口

说明可以 添加监听,这里把监听定义为

 

 public void addPropertyListener(IPropertyListener l) {

        addListenerObject(l);

    }

实际上还是添加到了 EventManager  中。

IPropertyListener 监听是对Viewpart 属性更改的监听。

 

    protected void setTitle(String title) {

        title = Util.safeString(title);

 

        //Do not send changes if they are the same

        if (Util.equals(this.title, title)) {

return;

}

        this.title = title;

        firePropertyChange(IWorkbenchPart.PROP_TITLE);

    }

 

    protected void firePropertyChange(final int propertyId) {

        Object[] array = getListeners();

        for (int nX = 0; nX < array.length; nX++) {

            final IPropertyListener l = (IPropertyListener) array[nX];

            try {

                l.propertyChanged(WorkbenchPart.this, propertyId);

            } catch (RuntimeException e) {

                WorkbenchPlugin.log(e);

            }

        }

    }



 

 

EventManager 该类在eclipse中用的也是很多的,很多类都实现了该对象。

                       功能:实现了对监听的维护(同步的)。

 

IPropertyListener                Viewpat属性更改的监听

 

 public void addPropertyListener(IPropertyListener l) {

        addListenerObject(l);

    }

 

下面的这个监听是IWorkbenchPart3中定义的。可以在ViewPart绑定一些数据数据存放在Map中,Map中的数据

有变化时,就会通知监听。

 

  public void addPartPropertyListener(IPropertyChangeListener listener) {

    partChangeListeners.add(listener);

    }

这样做是为了WorkbenchPart 具有更好的扩展性。

IWorkbenchPart3  官方定义

 

A part can provide arbitrary properties. The properties will be persisted between sessions by the part reference, and will be available from the part reference as well as the part. The properties can only be set on a part, not on the reference. The properties will be available to the IPresentablePart.

Setting a property must fire a PropertyChangeEvent. 

 

ViewPart就先研究到这里。

 

 

 

接下来我们重点研究一下org.eclipse.ui.workbench 

 

 

org.eclipse.ui.workbench  我们工作中使用的class基本上都在这个插件中实现的。

也算是  eclipse 的肌肉、骨骼了。

 

eclipse  大量使用了  Assert  类,来对参数的数据类型进行校正。

如何出现  断言的异常,可能就是 数据类型 不正确。

并且internal包下的都是对接口的实现。

 

基本目录:


在看NewWizardAction 源码中看到了

LegacyResourceSupport类,这个类就是加载不同插件的class的。

这里也说明了不同插件(Bundle)是通过不同的类加载器加载的。

 

 

 IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault()

                .getDialogSettings();

通过IDialogSettings  可以对wizard的数据进行持久化到 xml,并进行状态保存。

 

 

 

 

An interface to a storage mechanism for making dialog settings persistent. The store manages a collection of key/value pairs. The keys must be strings and the values can be either, strings or array of strings. Convenience API to convert primitive types to strings is provided.

 

 

 

 

    NewWizard wizard = new NewWizard();

        wizard.setCategoryId(categoryId);

wizard.setWindowTitle(windowTitle);

 

        ISelection selection = workbenchWindow.getSelectionService()

                .getSelection();

        IStructuredSelection selectionToPass = StructuredSelection.EMPTY;

        if (selection instanceof IStructuredSelection) {

            selectionToPass = (IStructuredSelection) selection;

        } else {

            // @issue the following is resource-specific legacy code

            // Build the selection from the IFile of the editor

            Class resourceClass = LegacyResourceSupport.getResourceClass();

            if (resourceClass != null) {

                IWorkbenchPart part = workbenchWindow.getPartService()

                        .getActivePart();

                if (part instanceof IEditorPart) {

                    IEditorInput input = ((IEditorPart) part).getEditorInput();

                    Object resource = Util.getAdapter(input, resourceClass);

                    if (resource != null) {

                        selectionToPass = new StructuredSelection(resource);

                    }

                }

            }

        }

 

        wizard.init(workbenchWindow.getWorkbench(), selectionToPass);

 

        IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault()

                .getDialogSettings();

        IDialogSettings wizardSettings = workbenchSettings

                .getSection("NewWizardAction"); //$NON-NLS-1$

        if (wizardSettings == null) {

wizardSettings = workbenchSettings.addNewSection("NewWizardAction"); //$NON-NLS-1$

}

        wizard.setDialogSettings(wizardSettings);

        wizard.setForcePreviousAndNextButtons(true);

 

        Shell parent = workbenchWindow.getShell();

        WizardDialog dialog = new WizardDialog(parent, wizard);

        dialog.create();

        dialog.getShell().setSize(

                Math.max(SIZING_WIZARD_WIDTH, dialog.getShell().getSize().x),

                SIZING_WIZARD_HEIGHT);

        PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),

IWorkbenchHelpContextIds.NEW_WIZARD);

        dialog.open();

 

 

这是eclipse 打开一个创建对话框的代码,可以借鉴一下。

这个插件内的很多代码大家都可以在做插件开发中借鉴一下的。

 

所有的IHandler 都是通过

CommandAction  来包装后执行的。

 

CommandAction  这里的 源码,看看还是有些启发的。

 

public class CommandAction extends Action {

 

private IHandlerService handlerService = null;

 

private ParameterizedCommand parameterizedCommand = null;

 

private ICommandListener commandListener;

 

protected CommandAction() {

 

}

 

/**

* Creates the action backed by a command. For commands that don't take

* parameters.

* @param serviceLocator

*            The service locator that is closest in lifecycle to this

*            action.

* @param commandIdIn

*            the command id. Must not be <code>null</code>.

*/

public CommandAction(IServiceLocator serviceLocator, String commandIdIn) {

this(serviceLocator, commandIdIn, null);

}

 

/**

* Creates the action backed by a parameterized command. The parameterMap

* must contain only all required parameters, and may contain the optional

* parameters.

* @param serviceLocator

*            The service locator that is closest in lifecycle to this

*            action.

* @param commandIdIn

*            the command id. Must not be <code>null</code>.

* @param parameterMap

*            the parameter map. May be <code>null</code>.

*/

public CommandAction(IServiceLocator serviceLocator, String commandIdIn,

Map parameterMap) {

if (commandIdIn == null) {

throw new NullPointerException("commandIdIn must not be null"); //$NON-NLS-1$

}

init(serviceLocator, commandIdIn, parameterMap);

}

 

protected ICommandListener getCommandListener() {

if (commandListener == null) {

commandListener = new ICommandListener() {

public void commandChanged(CommandEvent commandEvent) {

if (commandEvent.isHandledChanged()

|| commandEvent.isEnabledChanged()) {

if (commandEvent.getCommand().isDefined()) {

setEnabled(commandEvent.getCommand().isEnabled());

}

}

}

};

}

return commandListener;

}

 

/**

* Build a command from the executable extension information.

* @param commandService

*            to get the Command object

* @param commandId

*            the command id for this action

* @param parameterMap

*/

private void createCommand(ICommandService commandService,

String commandId, Map parameterMap) {

Command cmd = commandService.getCommand(commandId);

if (!cmd.isDefined()) {

WorkbenchPlugin.log("Command " + commandId + " is undefined"); //$NON-NLS-1$//$NON-NLS-2$

return;

}

 

if (parameterMap == null) {

parameterizedCommand = new ParameterizedCommand(cmd, null);

return;

}

 

parameterizedCommand = ParameterizedCommand.generateCommand(cmd,

parameterMap);

}

 

public void dispose() {

// not important for command ID, maybe for command though.

handlerService = null;

if (commandListener != null) {

parameterizedCommand.getCommand().removeCommandListener(

commandListener);

commandListener = null;

}

parameterizedCommand = null;

}

 

/*

* (non-Javadoc)

* @see org.eclipse.jface.action.Action#runWithEvent(org.eclipse.swt.widgets.Event)

*/

public void runWithEvent(Event event) {

if (handlerService == null) {

String commandId = (parameterizedCommand == null ? "unknownCommand" //$NON-NLS-1$

: parameterizedCommand.getId());

WorkbenchPlugin.log("Cannot run " + commandId //$NON-NLS-1$

+ " before command action has been initialized"); //$NON-NLS-1$

return;

}

try {

if (parameterizedCommand != null) {

handlerService.executeCommand(parameterizedCommand, event);

}

} catch (Exception e) {

WorkbenchPlugin.log(e);

}

}

 

/*

* (non-Javadoc)

* @see org.eclipse.jface.action.Action#run()

*/

public void run() {

// hopefully this is never called

runWithEvent(null);

}

 

protected void init(IServiceLocator serviceLocator, String commandIdIn,

Map parameterMap) {

if (handlerService != null) {

// already initialized

return;

}

handlerService = (IHandlerService) serviceLocator

.getService(IHandlerService.class);

ICommandService commandService = (ICommandService) serviceLocator

.getService(ICommandService.class);

ICommandImageService commandImageService = (ICommandImageService) serviceLocator

.getService(ICommandImageService.class);

 

createCommand(commandService, commandIdIn, parameterMap);

if (parameterizedCommand != null) {

setId(parameterizedCommand.getId());

setActionDefinitionId(parameterizedCommand.getId());

try {

setText(parameterizedCommand.getName());

} catch (NotDefinedException e) {

// if we get this far it shouldn't be a problem

}

parameterizedCommand.getCommand().addCommandListener(

getCommandListener());

parameterizedCommand.getCommand().setEnabled(

handlerService.getCurrentState());

setEnabled(parameterizedCommand.getCommand().isEnabled());

setImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_DEFAULT));

setDisabledImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_DISABLED));

setHoverImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_HOVER));

}

}

 

protected ParameterizedCommand getParameterizedCommand() {

return parameterizedCommand;

}

 

public String getActionDefinitionId() {

return super.getActionDefinitionId();

}

}

 

 

 还有org.eclipse.ui.internal.WorkbenchWindow    

这个就是我们的rcp 窗口的实现类。

继承 jface ApplicationWindow 。

 

 

接下来我们研究一下扩展定义的信息eclipse 是在哪里调用里面的信息,并动态的调用代码 

 

 

 

以action 为例 

 

可以在eclipse 作为菜单、工具栏、弹出菜单 有很几个扩展点都可以实现。

 

看eclipse  是如何使用扩展的配置信息的。

入口肯定在

 

org.eclipse.ui.internal.WorkbenchWindow 

 

 

 

private final void initializeDefaultServices() {

serviceLocator.registerService(IWorkbenchLocationService.class,

new WorkbenchLocationService(IServiceScopes.WINDOW_SCOPE,

getWorkbench(), this, null, null, null, 1));

// added back for legacy reasons

serviceLocator.registerService(IWorkbenchWindow.class, this);

final ActionCommandMappingService mappingService = new ActionCommandMappingService();

serviceLocator.registerService(IActionCommandMappingService.class,

mappingService);

 

final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(

this);

serviceLocator.registerService(LegacyActionPersistence.class,

actionPersistence);

actionPersistence.read();  //关键是这行代码。

 

}

这个是初始化方法。

 

 

方法的内容:

 

public final void read() {

clear();

LegacyActionPersistence.super.read();

 

// 创建 extension registry  

final IExtensionRegistry registry = Platform.getExtensionRegistry();

int actionSetCount = 0;

int editorContributionCount = 0;

int objectContributionCount = 0;

int viewContributionCount = 0;

int viewerContributionCount = 0;

final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];

 

// 1    actionSets  extension point.

final IConfigurationElement[] actionSetsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_ACTION_SETS);

for (int i = 0; i < actionSetsExtensionPoint.length; i++) {

final IConfigurationElement element = actionSetsExtensionPoint[i];

final String name = element.getName();

if (TAG_ACTION_SET.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_ACTION_SETS, actionSetCount++);

}

}

 

// 2     editorActions extension point.

final IConfigurationElement[] editorActionsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_EDITOR_ACTIONS);

for (int i = 0; i < editorActionsExtensionPoint.length; i++) {

final IConfigurationElement element = editorActionsExtensionPoint[i];

final String name = element.getName();

if (TAG_EDITOR_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_EDITOR_CONTRIBUTIONS, editorContributionCount++);

}

}

 

//     popupMenus extension point.

final IConfigurationElement[] popupMenusExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_POPUP_MENUS);

for (int i = 0; i < popupMenusExtensionPoint.length; i++) {

final IConfigurationElement element = popupMenusExtensionPoint[i];

final String name = element.getName();

                       //3  TAG_OBJECT_CONTRIBUTION

if (TAG_OBJECT_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_OBJECT_CONTRIBUTIONS, objectContributionCount++);

                     //4  TAG_OBJECT_CONTRIBUTION

} else if (TAG_VIEWER_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_VIEWER_CONTRIBUTIONS, viewerContributionCount++);

}

}

 

// 4   viewActions extension point.

final IConfigurationElement[] viewActionsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_VIEW_ACTIONS);

for (int i = 0; i < viewActionsExtensionPoint.length; i++) {

final IConfigurationElement element = viewActionsExtensionPoint[i];

final String name = element.getName();

if (TAG_VIEW_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_VIEW_CONTRIBUTIONS, viewContributionCount++);

}

}

 

readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],

actionSetCount);

readEditorContributions(

indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],

editorContributionCount);

readObjectContributions(

indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],

objectContributionCount);

readViewContributions(

indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],

viewContributionCount);

readViewerContributions(

indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],

viewerContributionCount);

}

 

 

代码解释:

final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];

这里一共有5中action的定义,所有这里的2维数组  的第一个参数为5了。

 

 

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_ACTION_SETS, actionSetCount++);

把读出来的 IConfigurationElement element  添加到对应  indexedConfigurationElements 二维数组中。

 

然后分别调用

 

readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],

actionSetCount);

readEditorContributions(

indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],

editorContributionCount);

readObjectContributions(

indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],

objectContributionCount);

readViewContributions(

indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],

viewContributionCount);

readViewerContributions(

indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],

viewerContributionCount);

 

对不同的action进行 初始化。

 

进入readActionSets中。

 

private final void readActionSets(

final IConfigurationElement[] configurationElements,

final int configurationElementCount) {

// 

// this was an even dumber fix than modifying the path

// 

// stupid navigate group

// SGroup nav = menuService.getGroup(STUPID_NAVIGATE);

// if (!nav.isDefined()) {

// nav.define(new SLocation(new SBar(SBar.TYPE_MENU, null)));

// }

// stupid navigate group

 

final List warningsToLog = new ArrayList(1);

 

for (int i = 0; i < configurationElementCount; i++) {

final IConfigurationElement element = configurationElements[i];

 

// Read the action set identifier.

final String id = readRequired(element, ATT_ID, warningsToLog,

"Action sets need an id"); //$NON-NLS-1$

if (id == null) {

continue;

}

 

// Read the label.

final String label = readRequired(element, ATT_LABEL,

warningsToLog, "Actions set need a label", //$NON-NLS-1$

id);

if (label == null) {

continue;

}

 

// Restrict the handler to when the action set is active.

final LegacyActionSetExpression expression = new LegacyActionSetExpression(

id, window);

 

 

// Read all of the child elements.

readActionsAndMenus(element, id,

warningsToLog, expression, null);

// Define the action set.

}

 

logWarnings(

warningsToLog,

"Warnings while parsing the action sets from the 'org.eclipse.ui.actionSets' extension point"); //$NON-NLS-1$

}

 

 

 

最后找到   WorkbenchMenuService   类中的populateContributionManager  方法 具体把扩展点的信息 

添加到了 具体的  menu中。

藏的好深。。。。

 

 

MenuLocationURI  这个类是对 menu [scheme]:[path]?[query]  的包装。

 

 

从定义扩展点 到  对扩展点的 调用  中间包装了很多层。 好多都是以service的形式提供的。

 

 

  • 大小: 17.7 KB
分享到:
评论
1 楼 zxjlwt 2015-08-13  
很好。

http://surenpi.com

相关推荐

    RAP源码泛读及分析

    【标题】"RAP源码泛读及分析" 【描述】这篇博客主要探讨了RAP框架的源码解析,作者通过深入研究RAP的内部实现,旨在帮助读者理解这个工具的工作原理,提高开发人员对RAP的理解和使用能力。虽然描述部分为空,但我们...

    泛读教程第四册答案.pdf

    泛读教程第四册答案.pdf

    英语泛读技巧总结PPT课件.pptx

    英语泛读技巧总结PPT课件 英语泛读技巧是英语学习中的一项重要技能,旨在快速了解英语文章或书籍的主要内容和大意。英语泛读技巧总结PPT课件为我们提供了英语泛读技巧的总结和指导。 一、英语泛读技巧的主要方法 ...

    英语泛读教程2:(第三版刘乃银).pdf

    英语泛读教程2:(第三版刘乃银).pdf 英语泛读教程是英语学习领域中的一本重要教材,本书旨在帮助读者提高英语阅读能力,掌握英语语言的基础知识。本书共分为两部分,第一部分为语法基础,第二部分为阅读理解。 ...

    英语泛读教程1:(第三版刘乃银).pdf

    英语泛读教程1:(第三版刘乃银).pdf

    英语泛读教程UnitFool'sParadisePPT课件.pptx

    英语泛读教程UnitFool'sParadisePPT课件.pptx

    Android 小米便签源码-IT计算机-毕业设计.zip

    本资源提供的是小米便签的源码,对于学习Android应用开发,尤其是想要深入理解应用内核机制的学生来说,这是一个宝贵的实践资料。下面将围绕这个主题,详细讲解Android应用开发中的关键知识点。 1. **Android ...

    高二英语泛读PPT课件.pptx

    这篇高二英语泛读PPT课件主要围绕一次伦敦之旅展开,通过快速阅读和仔细阅读的形式,引导学生了解关于伦敦的历史文化、名胜古迹以及奥运会的相关知识。 1. **奥林匹克运动会相关知识**: - 29th Olympic Games(第...

    大学英语泛读_第一册_答案{全)..docx

    【大学英语泛读】课程是大学英语教学的重要组成部分,旨在提升学生的阅读理解能力和词汇量,同时帮助学生掌握常用短语和表达。以下是针对四课内容的解析和知识点总结: 第一课: 1. 阅读理解题目测试了学生对文章...

    大学英语泛读第一册答案{全)知识讲解.docx

    【大学英语泛读第一册答案{全)知识讲解】 这篇文档是关于大学英语泛读课程的知识讲解,包含多个课时的练习答案和重点词汇解析,旨在帮助学生巩固阅读理解能力和学习英语常用短语及表达。 在Lesson 1的...

    UnitClimate泛读教程实用教案.pptx

    这篇文档是关于“UnitClimate”的泛读教程,旨在教授与气候相关的英语词汇和概念,同时融入了阅读理解的教学策略。教程分为多个部分,包括预测试、气候定义、气候类型、气候灾难、气候变化以及文本阅读与分析。 ...

    绝对真实英语泛读教程刘乃银三二册全册所有单元答案PPT课件.pptx

    刘乃银三二册英语泛读教程课件PPT概述 本资源是《刘乃银三二册英语泛读教程》的课件PPT,共16页,涵盖Book 2的Unit 1-9。每个单元包括Text、Fast Reading和Home Reading三部分,每部分都提供了答案.keys和解释。 ...

    英语泛读教程1课文翻译.docx

    这篇文档讲述了《英语泛读教程》第一课的内容,是一篇关于美国作家劳拉·英格尔·威尔德生活故事的翻译。这个故事发生在19世纪70年代的威斯康辛州,描绘了劳拉一家在大森林边上的小木屋生活的情景。故事的核心事件是...

    雅思阅读之精读泛读结合法.docx

    【雅思阅读之精读泛读结合法】 雅思阅读考试中,精读与泛读的结合是一种有效的备考策略,旨在帮助考生提升词汇量、积累背景知识并增强阅读能力。以下是这两种方法的具体应用及其益处。 一、精读的重要性 精读指的...

    大学英语泛读教程UnitPPT课件.pptx

    在中国文化中,数字有着深远的影响,特别是在日常生活中。这些数字不仅仅是数学上的概念,它们与预兆、幸运和传统文化紧密相连。 首先,数字“一”(ONE)象征着开始和独立。它代表单一、纯粹,有时也被用来祈求...

    大学英语泛读教程二Getting enough sleepPPT课件.pptx

    "大学英语泛读教程二Getting enough sleepPPT课件.pptx" 本资源围绕"Getting enough sleep"这个主题,旨在帮助学生掌握相关的英语阅读和理解技巧。下面是从该资源中提炼出的知识点: 1. Sleep Debt的概念:Sleep ...

    大数据-算法-汉语中级泛读教材难度定量分析.pdf

    在本篇论文中,作者探讨了“大数据-算法”如何应用于汉语中级泛读教材难度的定量分析。文章首先介绍了汉语泛读教材的重要性和易读性研究的背景,指出当前中级汉语泛读教材在难度控制方面存在一些问题。为了量化这些...

    英语专业泛读读物.doc

    英语专业泛读读物.doc

    互联网时期英语泛读教学初探.pdf

    【互联网时期英语泛读教学初探】 随着互联网的快速发展,英语泛读教学也迎来了新的机遇。互联网提供的丰富资源为教学提供了无限可能,不仅内容全面、类型多样,而且更新迅速、检索便捷,使得教师能够轻松筛选出符合...

    大学英语泛读(2)教学大纲.doc

    "大学英语泛读(2)教学大纲.doc" 本资源是一个大学英语泛读(2)的教学大纲,旨在提高学生的英语阅读能力和知识储备。课程涵盖政治、经济、军事、文化、历史、天文等多个领域的文章资料,旨在增强学生的阅读理解能力...

Global site tag (gtag.js) - Google Analytics