热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

十五、应用遥测与应用洞察

十五、应用遥测与应用洞察敏捷应用生命周期管理规定,在应用发布后,应该将性能和用户反馈引入开发周期

十五、应用遥测与应用洞察

敏捷应用生命周期管理规定,在应用发布后,应该将性能和用户反馈引入开发周期。 反馈信息可以为如何从业务和技术角度改进应用提供重要的线索。 Application Insights 可以从使用 Azure 托管的 web 服务基础设施的 Xamarin 应用中收集遥测数据,因为它与 Azure 模块进行了内在集成,并且具有用于 App Center 遥测的持续导出功能。

在本章中,我们将分析两种不同的遥测源,即 App Center 和 Application Insights 的数据模型和利用。 我们将看看 sdk 以及这些平台为用户遥测提供了什么。 以下章节将指导你完成本章:


  • 收集 Xamarin 应用的见解

  • 为 Azure 服务收集遥测数据

  • 分析数据

在本章的最后,您将能够将 App Center 遥测客户端集成到您的 Xamarin 应用中,并收集有价值的用户遥测数据。 您还将学习如何将这些遥测数据迁移到 Application,并使用高级查询模型和可视化对其进行分析。

收集 Xamarin 应用的见解

在本节中,我们将重点讨论 App Center 遥测技术以及如何扩展用户遥测的范围。

正如我们之前讨论和设置的,Xamarin 应用中的应用遥测是通过 App Center SDK 收集的。 该应用数据虽然提供了关于应用使用模式的关键信息,但不能在 App Center 中进一步分析。 我们首先需要将 App Center 标准以及自定义遥测数据导出到 Azure Application Insights 资源中,以便可以使用查询语言执行进一步的分析。

遥测数据模型

通过使用 App Center SDK,可以与事件一起收集遥测信息,事件可以包含关于特定用户操作或应用执行模式的附加信息。 这些额外的数据点,也被称为维度,通常用于给用户提供用于执行触发遥测事件的函数的数据的快速快照。 简单地说,遥测事件可以描述为事件名称和该事件的其他维度。 让我们从创建遥测模型开始:


  1. First, create a telemetry event, as follows:

    ```
    public abstract class TelemetryEvent
    {
    public TelemetryEvent()
    {
    Properties = new Dictionary();
    }
    public TelemetryEvent(string eventName) : this()
    {
    Name = eventName;
    }
    public string Name { get; private set; }

    public virtual Dictionary Properties { get;
    set; }

    }
    ```

    重要提示

    任何自定义事件都将包含标准的跟踪元数据,例如操作系统版本、请求的地理区域、设备模型、应用版本,等等。 不需要将这些属性记录为附加维度。 属性应用于特定于事件的数据。


  2. 现在,使用 App Center SDK 实现遥测 writer:


  3. 为了扩展事件定义以包含Exception属性,我们可以为错误添加额外事件。 换句话说,我们可以跟踪应用中处理的异常:

    public void TrackEvent(TelemetryEvent @event)
    {
    if(@event.Exception != null)
    {
    TrackError(@event);
    return;
    }
    Analytics.TrackEvent(@event.Name, @event.Properties);
    }
    public void TrackError(TelemetryEvent @event)
    {
    Crashes.TrackError(@event.Exception, @event.Properties);
    }


  4. 现在,开始创建定制事件并开始记录遥测数据。 我们的初始事件可能是登录事件,这通常是用户会话的起始位置:

    ```
    public class LoginEvent: TelemetryEvent
    {
    public LoginEvent() : base("Login")
    {
    Properties.Add(nameof(Result), string.Empty);
    }

    public string Result
    {
    get
    {
    return Properties[nameof(Result)];
    }
    set
    {
    Properties[nameof(Result)] = value;
    }
    }

    }
    ```


  5. 登录后,用户将导航到主仪表板,因此我们将以类似的方式记录我们的仪表板出现事件:

    ```
    protected override void OnAppearing()
    {
    base.OnAppearing();

    App.Telemetry.TrackEvent(new HomePageEvent()
    {
    LoadedItems = ViewModel.Items.Count.ToString()
    });

    }
    ```


  6. Additionally, define navigation to the details view, where various actions can be executed by the user:

    ```
    protected override void OnAppearing()
    {
    base.OnAppearing();

    App.Telemetry.TrackEvent(new DetailsPageEvent()
    {
    SelectedItem = viewModel.Title
    });

    }
    ```

    重要提示

    App Center 可以跟踪的事件结构有一定的限制。 自定义事件名称最多不能超过 200 个。 此外,事件名称的长度限制为 256 个字符,而属性名称不能超过 125 个字符。


  7. 结果元数据现在可以在 App Center 仪表盘板上显示:


Figure 15.1 – App Center Data Visualization

图 15.1 - App Center 数据可视化

到目前为止,在本节中,我们已经使用自定义事件创建了一个小型页面跟踪器。 在本节的下一部分中,我们将尝试组织应用交付的遥测事件。

高级应用遥测

在前面的示例中,我们为遥测编写器实例使用了静态访问器。 然而,这个实现可能会导致严重的架构问题,其中最重要的是我们将应用类与 App Center SDK 的具体实现耦合。

为了解决可能出现的架构问题,让我们创建一个代理遥测容器,将遥测请求转移到目标遥测写入器。 为此,遵循以下步骤:


  1. 首先创建一个ITelemetryWriter接口来抽象我们的 App Center 遥测处理程序:

    ```
    public interface ITelemetryWriter
    {
    string Name { get; }
    void TrackEvent(TelemetryEvent @event);

    void TrackError(TelemetryEvent @event);

    }
    ```


  2. Now, create a proxy container:

    ```
    public class AppTelemetryRouter : ITelemetryWriter
    {
    // Removed for Brevity

    public static AppTelemetryRouter Instance
    {
    get
    {
    if(_instance == null)
    {
    _instance = new AppTelemetryRouter();
    }
    return _instance;
    }
    }
    public void RegisterWriter(ITelemetryWriter telemetryWriter)
    {
    if(_telemetryWriters.Any(tw=>tw.Name ==
    telemetryWriter.Name))
    {
    throw new InvalidOperationException($"Already
    registered Telemetry Writer for
    {telemetryWriter.Name}");
    }
    _telemetryWriters.Add(telemetryWriter);
    }
    public void RemoveWriter(string name)
    {
    if(_telemetryWriters.Any(tw => tw.Name == name))
    {
    var removalItems = _telemetryWriters.First(tw =>
    tw.Name == name);
    _telemetryWriters.Remove(removalItems);
    }
    }
    public void TrackEvent(TelemetryEvent @event)
    {
    _telemetryWriters.ForEach(tw => tw.TrackEvent(@event));
    }
    public void TrackError(TelemetryEvent @event)
    {
    _telemetryWriters.ForEach(tw => tw.TrackError(@event));
    }

    }
    ```

    同样重要的是,容器应该在定义视图模型的跨平台项目上创建,因为大多数诊断遥测实际上是在视图模型而不是视图本身上收集的。 这个实现的另一个优点是,我们现在可以为不同的平台定义多个遥测编写器,比如 Firebase、Flurry Analytics 等等。

    虽然抽象的遥测事件类提供了基本数据,但它不提供关于执行时间的任何指标。 例如,如果我们正在执行一个远程服务调用或一个长时间运行的操作,执行时间可能是一个有价值的维度。


  3. 为了收集这个特定的度量,创建一个额外的遥测对象:

    ```
    public abstract class ChronoTelemetryEvent : TelemetryEvent
    {
    public ChronoTelemetryEvent()
    {
    Properties.Add(nameof(Elapsed), 0.ToString());
    }

    public double Elapsed
    {
    get
    {
    return double.Parse(Properties[nameof(Elapsed)]);
    }
    set
    {
    Properties[nameof(Elapsed)] = value.ToString();
    }
    }

    }
    ```


  4. 现在,创建一个跟踪器对象,它将跟踪需要执行时间度量的事件的执行时间:

    ```
    public class TelemetryTracker : IDisposable
    where TEvent : ChronoTelemetryEvent
    {
    private readonly DateTime _executiOnStart= DateTime.Now;

    public TelemetryTracker(TEvent @event)
    {
    Event = @event;
    }
    public TEvent Event { get; }
    public void Dispose()
    {
    var executionTime = DateTime.Now - _executionStart;
    Event.Elapsed = executionTime.TotalMilliseconds;
    // The submission of the event can as well be moved out of
    //the tracker
    AppTelemetryRouter.Instance?.TrackEvent(Event);
    }

    }
    ```


  5. 现在,使用我们的跟踪器对象,我们可以在应用中收集关于时间敏感操作的有价值的信息:

    ```
    public async Task LoadProducts()
    {
    using (var telemetry = new TelemetryTracker(new ProductsRequestEvent()))
    {
    try
    {
    var result = await _serviceClient.RetrieveProducts();

    Items = new ObservableCollection(
    result.Select(item => ItemViewModel.FromDto(item)));
    }
    catch (Exception ex)
    {
    telemetry.Event.Exception = ex;
    }
    }

    }
    ```


  6. The results of the service call are measured with the Elapsed metric, which can be observed in the App Center's LogFlow:

    Figure 15.2 – App Center Log Flow

    图 15.2 - App Center 日志流程


  7. 类似地,跟踪器对象可以在某些视图的OnAppearing事件上创建,并在OnDisappearing事件上处理,这样我们就可以跟踪用户在某个视图上花费了多少时间。


虽然 App Center 提供了一种方便的方法来收集遥测数据,但为了执行对用户模式的分析并排除应用问题,我们可以将遥测数据导出到 application Insights。

导出 App Center 遥测数据到 Azure

此时,应用正在收集遥测数据并将其推送到 App Center。 但是,正如我们前面讨论的,您将不能进一步分析这些数据——特别是自定义事件维度。

为了做到这一点,我们需要创建一个新的 Application Insights 资源,并设置一个连续的导出,以便 App Center 遥测数据可以导出为 Application Insights 数据。 让我们开始:


  1. Start this process by creating the Application Insights resource:

    Figure 15.3 – Export to Application Insights

    图 15.3 -导出到应用洞察

    注意,对于应用类型,我们选择了App Center 应用。 作为一个资源组,我们将使用与前面创建的 Azure 服务相同的资源组,以便可以将完整的 Azure 基础设施部署在一起。


  2. Once the resource is created, go to the Overview section to find the instrumentation key. This key is the only requirement for setting up the continuous export process:

    Figure 15.4 – Application Insights for Xamarin Telemetry

    图 15.4 - Xamarin 遥测技术的应用观察


  3. On App Center, in order to set up the export, navigate to the Settings section and select Export and Application Insights on the data export window.

    在此视图中,您可以使用设置标准导出选项,当将 Azure 订阅配置为与 App Center 一起使用时使用该选项。 选择标准导出需要管理员访问 Azure 订阅,并创建一个新资源。 您还可以选择Customize并粘贴到我们从 Azure 门户获得的仪表键中。


  4. 在此设置之后,事件遥测将定期推送到Application Insights,可以在 Azure 门户中使用标准分析部分或使用查询语言进行分析:


Figure 15.5 – Application Insights User Telemetry

图 15.5 -应用观察用户遥测

本节主要讨论 App Center 遥测技术。 我们从使用自定义事件的基本用户遥测开始,扩展到高级操作诊断数据。 如您所见,通过对遥测模型进行小的调整,您可以获得对常见用户流的宝贵见解,这有助于引导您的应用走向成功。 现在我们已经收集了应用中的遥测数据并导出到 application Insights,我们可以开始为 Azure 上的其余模块创建 application Insights 基础设施了。

为 Azure 服务收集遥测数据

与移动应用相比,Application Insights 与基于 azure 的服务的集成要更紧密一些。 除了可以为诸如 Azure App Service 等的服务和诸如 Azure 函数等无服务器组件收集的各种标准的开箱即开的遥测技术之外,还可以实现定制的遥测技术、跟踪和度量收集实现。

应用洞察数据模型

遥测采集可以分为三大类:


  • 痕量:痕量可以识别为最简单的遥测形式。 跟踪元素通常给出事件的标称描述,并用作诊断日志,类似于其他平面文件诊断日志实现。 除了主要的遥测信息外,还可以定义严重性级别和其他属性。 跟踪消息的大小限制比其他遥测类型要大得多,并且提供了提供大量诊断数据的方便方法。 当在。net 5.0 应用中使用标准日志扩展时,也会使用跟踪模型。

  • 事件:Application Insights 事件与 App Center 遥测项目非常相似,在将 App Center 数据导出到 Application Insights 后,处理方式相同。 除了名义维度之外,还可以将其他度量数据发送到 Application Insights。 一旦收集了数据,customProperties集合提供了对描述性维度的访问,而customMeasurements字典用于访问度量。

  • 度量:它们通常是预先聚合的标量度量。 如果您正在处理自定义指标,则应用有责任使其保持最新。 Application Insights 客户端为标准和定制指标提供了标准化的访问方法。

除了特定于事件的遥测数据类型外,还可以使用 Application Insights 跟踪特定于操作的数据类型,例如请求、异常和依赖关系。 这些数据被归为更广义的宏观级遥测数据,它们可以提供关于应用基础结构健康状况的有价值的信息。 默认情况下,通常会跟踪请求、异常和依赖数据,但也可以自定义/手动实现。

利用 ASP 技术采集遥测数据.NET Core

应用洞察可以很容易地使用 Visual Studio 对任何 ASP 进行初始化.NET Core web 应用。 在我们的例子中,我们将配置 web API 层来使用 Application Insights。 让我们看看如何做到这一点:


  1. 首先右键单击 web 应用项目,然后选择Add | application Insights Telemetry,然后单击Get Started链接。 Visual Studio 自动加载与您的帐户相关联的资源,允许您选择订阅以及资源/资源组对。

  2. Use the Configure Settings... option on this page to assign an already existing resource group; otherwise, the Application Insights instance will be created on a default Application Insights resource group:

    Figure 15.6 – Application Insights Configuration

    图 15.6 -应用洞察配置

    Application Insights配置完成后,我们可以看到如何收集遥测数据,而无需将 web API 部署到 Azure App Service 资源中。


  3. In order to see the collected telemetry data, you can start a debugging session. Select View | Other Windows | Application Insights to open the live Application Insights data that is collected within the debug session:

    Figure 15.7 – Application Insights Debug Session Telemetry

    图 15.7 -应用观察调试会话遥测

    需要注意的是,数据被设置为使用调试会话遥测Application Insights Search工具集还可以用于读取远程遥测数据并对实时数据执行快速搜索查询。

    另一个有用的工具窗口是Application Insights Trends,它是针对各种应用遥测数据类型(如请求、页面视图、异常、事件和依赖项)的快速报告工具。

    同样的遥测集,即使这是一个调试会话,也应该已经在 Azure 门户上可用了。 换句话说,Application Insights 不需要部署 Azure 就可以对服务器资源进行分析,并对其进行遥测跟踪。


  4. 现在,如果导航到 Application Insights 概览页面,您将注意到关于请求的传入数据和收集到的遥测数据。


  5. Next, navigate to the live metrics screen using the side panel navigation. The live metrics screen can provide information about the server's performance and aggregated metrics data. In order to use profiling and performance data, update the Application Insights SDK to a version higher than 2.2.0 so you can see this:

    Figure 15.8 – Application Insights Live Metrics Stream

    图 15.8 -应用洞察实时指标流

    现在已经设置了 Application Insights 基础设施,我们可以开始创建定制的遥测和跟踪数据了。


  6. 为产品检索 API 操作创建一个新的操作上下文,并包括一些额外的遥测数据:

    using (var operatiOnContext= _telemetryClient.StartOperation("getProducts"))
    {
    var result = Enumerable.Empty();
    _telemetryClient.TrackTrace("Creating Document Client",
    SeverityLevel.Information);
    using (var document = GetDocumentClient())
    {
    try
    {
    _telemetryClient.TrackTrace("Retrieving Products",
    SeverityLevel.Information);
    result = await document.Retrieve();
    }
    catch (Exception ex)
    {
    _telemetryClient.TrackException(ex);
    operationContext.Telemetry.RespOnseCode= "500";
    throw ex;
    }
    }
    operationContext.Telemetry.RespOnseCode= "200";
    return Ok(result);
    }


  7. Now, the resultant telemetry collection that contains trace entries is automatically grouped to the operation context, thus providing more meaningful information:

    Figure 15.9 – Application Insights Operation Context

    图 15.9 -应用观察操作上下文

    我们可以通过分离依赖遥测来进一步细化这些遥测数据。 例如,在这个实现中,我们调用数据提供程序客户机来加载所有产品。


  8. 使用遥测客户端,为这个请求创建一个依赖遥测:

    using (var document = GetDocumentClient())
    {
    var callStartTime = DateTimeOffset.UtcNow;
    try
    {
    _telemetryClient.TrackTrace("Retrieving Products",
    SeverityLevel.Information);
    result = await document.Retrieve();
    }
    finally
    {
    var elapsed = DateTimeOffset.UtcNow - callStartTime;
    _telemetryClient.TrackDependency(
    "DataSource", "ProductsDB", "Retrieve", callStartTime,
    elapsed, result.Any());
    }
    }


  9. 现在,对文档源单独跟踪应用遥测。 这个依赖甚至是在 Azure 门户上的应用地图上创建的:


Figure 15.10 – Application Insights Application Map

图 15.10 - Application Insights Application Map

在正常情况下,对 Cosmos DB 和 SQL 等资源的依赖调用会分别自动检测和跟踪。 前面的实现适合外部依赖或遗留系统。

正如您在本部分所看到的,从 ASP 收集定制的遥测技术.NET 5 应用主要依赖于使用遥测客户端和通过 SDK 提供的特性。 大多数依赖遥测,以及异常,已经由客户端自动收集。 现在让我们转向 Azure 函数。

利用 Azure 功能采集遥测数据

当我们谈到自定义跟踪时,从 Azure 函数中收集 Application Insights 遥测数据与使用任何其他. net 应用没有什么不同。 在创建 Azure 函数时,我们在方法中注入了一个TraceWriter实例。 TraceWriter日志是诊断遥测的主要来源,是在 Azure 功能中收集的。 通过host.json设置可以根据日志级别对这些日志条目进行过滤:

{
"logger": {
"categoryFilter": {
"defaultLevel": "Information",
"categoryLevels": {
"Host.Results": "Error",
"Function": "Error",
"Host.Aggregator": "Information"
}
},
"aggregator": {
"batchSize": 1000,
"flushTimeout": "00:00:30"
}
},
"applicationInsights": {
"sampling": {
"isEnabled": true,
"maxTelemetryItemsPerSecond" : 5
}
}
}

类别级别中的 Function 部分引用在函数中收集的跟踪。 Host.Results是自动收集的请求/结果遥测数据对,而聚合器数据中充满了函数的主机默认收集的聚合指标,每 30 秒收集一次或 1,000 个结果。 然后使用它来计算聚合度量,例如计数、成功率等等。

除了基本的遥测实现之外,您还可以使用 Application Insights 遥测客户端修改默认的遥测数据。 在这种情况下,遥测客户端用于修改操作上下文,而不是创建一个新的TrackRequest

如您所见,遥测客户机在此实现中更像中间件而不是真相源,只是修改现有操作上下文并创建额外的事件数据。

在本节中,我们研究了不同的遥测模型,以及如何在 ASP 中使用它们.NET 应用以及 Azure 无服务器组件。 我们使用遥测客户端在我们的 web 服务中提供定制的遥测数据,同时在我们的 Azure 功能中使用 Application Insights 的标准配置。 现在我们已经在移动和网络平台上收集了足够的遥测数据,我们可以开始分析这些数据集了。

数据分析

现在我们已经在服务器端和应用端建立了 Application Insights 遥测收集,我们可以尝试理解这些数据。

虽然 Azure 门户提供了对应用遥测数据的快速洞察,但如果我们想真正深入研究应用数据,应该使用 application insights 门户进行分析。 在 Application Insights 门户中,可以使用查询语言分析数据。 查询语言,也称为 Kusto 语言,提供高级只读查询特性,可以帮助组织来自多个源的数据,并提供对应用的性能和使用模式的有价值的见解。

例如,让我们看看下面的简单查询,它是在我们的 Xamarin 遥测数据上执行的。 我们将返回从 App Center 导出的前 50 个自定义事件:

customEvents
| limit 50

这些遥测条目在根目录中包含了与遥测相关的一般数据:

Figure 15.11 – Application Insights Telemetry Details

图 15.11 -应用观察遥测详细信息

customDimensions对象提供更多的 xamarin 特定数据:

Figure 15.12 – Application Insights Custom Dimensions

图 15.12 -应用观察自定义维度

最后,customDimensionsProperties节点提供使用AppCenter遥测客户端发送的实际自定义遥测数据。 经过一些预处理后,我们可以将这个数据纳入我们的分析:


  1. 在深入研究特定于事件的数据之前,请使用遥测事件名称

    customEvents
    | where name == "ProductsServiceRequest"

    过滤遥测事件。
    2. 然后,根据时间戳对表进行排序:

    | order by timestamp desc nulls last


  2. 通过将属性数据反序列化为一个动态字段,在我们的查询中使用获取的数据:


  3. 为了扁平化表结构,将属性数据分配到其自己的字段:

    | extend Duration = todouble(Properties.elapsed), OperatingSystem = customDimensions.OsName


  4. 最后,将数据投影到一个新表中,这样我们就可以用更简单的结构来表示它:

    | project OperatingSystem, Duration, timestamp


  5. Now, the data from our telemetry events is structured and can be presented in reports and troubleshooting:

    Figure 15.13 – Operating System Projection

    图 15.13 -操作系统投影


  6. 为了更进一步,我们还可以使用最后的表格绘制一个图表,如下:

    | render timechart


  7. 这将绘制一个带有持续时间值的折线图。 您还可以通过使用summarize函数和多个聚合函数对数据进行排序,例如将事件分组到每小时的容器中,并绘制基于时间的条形图:

    customEvents
    | order by timestamp desc nulls last
    | extend Properties = todynamic(tostring(customDimensions.Properties))
    | summarize event_count=count() by bin(timestamp, 1h)
    | render barchart


Application Insights 数据和可用的查询操作符和方法为开发人员提供了无数方法,通过从登台环境或生产环境收集宝贵的应用数据并将其反馈给应用生命周期,从而主动地对应用遥测进行操作。

总结

从服务器端和客户端收集的应用遥测数据可以提供根据用户需求改进和塑造应用所需的信息。 在某种程度上,通过从实时环境中应用的各个模块收集应用遥测数据,使用实际的用户数据执行实时应用测试。 这些遥测数据可以提供其他自动化测试无法提供的应用洞察。 无论数据是真实的还是合成的,单元测试以及自动化 UI 测试都应该是应用生命周期的一部分。

在下一章中,我们将研究各种测试方法,以及如何在开发管道中包含这些测试。


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有