質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

2945閲覧

xamarin.androidでヤフーのHTML解析で、エミュでは出来ても実機では出来ない

tokuo

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/07/05 10:38

編集2016/07/05 10:48

xamarin.android(Visual Studio)を用いて
ヤフーのhtmlから<title>タグの中の「Yahoo! JAPAN」を抜き出そうとしているのですが、
エミュレータではうまく取得、表示できてもても、
実機では「問題が発生しました」とエラーをはいて出来ません。
すごくざっくりと聞きますが、どのようすれば解決するか教えてください。

c#

1using System; 2using Android.App; 3using Android.Widget; 4using Android.OS; 5using hap = HtmlAgilityPack; 6using System.Linq; 7 8 9namespace App1 10{ 11 [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")] 12 public class MainActivity : Activity 13 { 14 protected override void OnCreate(Bundle bundle) 15 { 16 base.OnCreate(bundle); 17 18 // Set our view from the "main" layout resource 19 SetContentView(Resource.Layout.Main); 20 21 // Get our button from the layout resource, 22 // and attach an event to it 23 Button button = FindViewById<Button>(Resource.Id.MyButton); 24 25 button.Click += delegate { 26 27 string url = "http://www.yahoo.co.jp/"; 28 29 System.Net.WebClient web = new System.Net.WebClient(); 30 string htmlSource = web.DownloadString(url); 31 hap.HtmlDocument html = new hap.HtmlDocument(); 32 html.LoadHtml(htmlSource); 33 var tags = html.DocumentNode.Descendants("title").Last().InnerText; 34 35 button.Text = tags; 36 }; 37 } 38 } 39}

動作環境等
・xamarin.android(Visual Studio 2015)
・API19
・android4.4
・実機(sharp sh-01F)
・HtmlAgilityPack利用

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amay077

2016/07/05 11:34

どの行を実行するとエラーが発生するのでしょうか? Release+実機であっても、ソースコードの後端からコメントアウトしていくなど、 エラーの箇所を特定することはできると思います。 あるいは、 ``try 〜 catch`` の例外処理を行って落ちなくなるのかどうかなど。
tokuo

2016/07/05 12:23

string htmlSource = web.DownloadString(url); この処理を行うとエラーが発生します
guest

回答2

0

ベストアンサー

エラーの内容と直接関係があるかは不明ですが、
button を押した時の処理が「ネットワーク通信を使用した」「時間のかかる」処理であり、
これは Android アプリ開発では(iOS や 最近の Windows でもそうですが)、以下の2つの問題があります。

  1. メインスレッドから通信処理を行うことは禁止されており、行った場合 NetworkOnMainThreadException 例外が発生する - 参考: [Android] AsyncTask を使わないと NetworkOnMainThreadException になります
  2. メインスレッドで時間のかかる処理を行うと「応答がありません」的なダイアログボックスが表示される(これは「ANR」と呼ばれています) - 参考: Androidアプリを高速化しよう -ANR編- - Just for Fun

そのため、これらの処理は「別スレッド」で行う必要があります。

Xamarin.Android では、 C# の Task や async/await 機能を使って、通信と HtmlAgilityPack の処理を、別スレッドで行わせることができます。
以下のようなコードです。

<省略> using System.Threading.Tasks; namespace App1 { [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { protected override void OnCreate(Bundle savedInstanceState) { <省略> button.Click += async delegate { var tags = await Task.Factory.StartNew<string>(() => { string url = "http://www.yahoo.co.jp/"; System.Net.WebClient web = new System.Net.WebClient(); string htmlSource = web.DownloadString(url); hap.HtmlDocument html = new hap.HtmlDocument(); html.LoadHtml(htmlSource); return html.DocumentNode.Descendants("title").Last().InnerText; }); button.Text = tags; }; } } }

ただ、時間のかかる処理を行っている最中、アプリは操作可能になっているので、別途ボタンをロックさせるなどの処理が必要です。

投稿2016/07/05 13:22

amay077

総合スコア1075

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tokuo

2016/07/05 14:06 編集

releaseではまだ起動しませんが、非常に参考になりました
tokuo

2016/07/05 15:14 編集

エラー部のStringにhtmlから取得した文字列を入れすぎてるのが原因だとおそらくですがわかりました。 ヒープに関するエラーをはかないように頑張ります。 どなたか、出来ればそのことに関して詳しいかたがいれば、適切なコードの書き方を教えてください。
amay077

2016/07/05 17:42

https://teratail.com/questions/40083 の質問からの推測ですが、 Load メソッドが使えなかったために WebClient で文字列として内容を読みだしてから LoadHtml を使われていると思うのですが、40083 の質問で TAKA_0921 さんがコメントされているように、Load の代わりに LoadFromWebAsync を使えばよいのではないでしょうか?
tokuo

2016/07/06 14:54

c#開発の勉強のためにも色々な方法で試したいので、こっちでも成功させたいです。 調べてみた感じ、release buildでのみエラーはヒープに関わることらしいのですが、解決法がいまだに分かりません。 今はとりあえず、非同期通信について勉強中です。
amay077

2016/07/06 16:01

web.DownloadString(url) は、指定したURLのレスポンスを文字列として全て一気に返すので、ヒープメモリが足りなくなる可能性は高くなるでしょう。 このような取得元のデータサイズが不確定な場合は、「一気に読みだす」プログラムを書くのは悪手です。WebClientでできるのかは不明ですが「少しずつ読んで処理した後、捨てる」を行う必要があります。 HtmlAgilityPack の LoadFromWebAsync でも同様の問題が発生するのであれば、これの採用自体も見なおした方が良いと思います。 あまり良い選択とは言えませんが、Androidアプリに割り当てるヒープ領域を増やす方法もあります。 * [[Android]アプリに割り当てられるヒープ領域を拡大(ハニカム以降対応) | Coffee Breakにプログラミング備忘録](http://to-developer.com/blog/?p=637)
tokuo

2016/07/06 17:50

わざわざありがとうございます。
guest

0

ReleaseではなくDebugでなら実機でも作動しました。
Releaseでも起動できる方法を教えてください。

投稿2016/07/05 10:58

編集2016/07/05 11:15
tokuo

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問