Introduction
Here, Once again I am back with another article in my series of MonoAndroid, for
previous article refers at bottom portion. In this article I am going to demonstrate
using ASMX Web Service (Non-WCF) in Mobile App.
Web services are becoming integrated part of mobile and web applications. Mono Android
support almost all type of Web Services like Restful, WCF and normal SOAP based
web services. In this article I am going to create dotnet based web service and
consuming same in my mobile application.
In this article I will create Software Developer Hierarchy app. In this we will
create dotnet web service, where we provide web method which will send the list
of software person with their designations and show them on our android mobile ListView.
Step By Step we move forward
- Create Android application by selecting New ->Solutions and
provide its name “
MonoWebService
”
Figure 1: Creating Android Project!
-
Now by default, when you create project in the android, it contain a button. So
application flow would be on click of button, we will invoke web service and fill
the ListView with the retrieved data.
So Button text contains “Hello World” and when we check button properties, it will
show its referring to string resource, Means button label is coming from string
table.
Now to change text on the button, you have to modify strings.xml under Resources\values.
Just look for name “hello” and change the name to “Retrieve Data from Web service”.
See i marked line in bold.
="1.0"="utf-8"
<resources>
<string name="hello">Retrieve Data from Web service</string>
<string name="app_name">MonoWebService</string>
</resources>
- Now add the ListView in the MainActivity file, after adding that, UI code looks
something like this :-
="1.0"="utf-8"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:id="@+id/Main_ListView" />
</LinearLayout>
-
Now time if for you to create web service in visual studio 2010. Now open the “Create
New Project”, change .Net framework 3.5 to make ASP.NET Web Service Application project available for selection.
Now create the project by name “MonoAndroidWebService“
-
Now change the name of default Service1
to MonoDataService
and delete anything else there. Now add GetWebServiceMonoDatas()
method which returns hardcoded list of WebServiceMonoData
public class MonoDataService : System.Web.Services.WebService
{
[WebMethod]
public List<WebServiceMonoData> GetWebServiceMonoDatas()
{
var lstFragmentDemo = new List<WebServiceMonoData>
{
new WebServiceMonoData()
{
Name = "Alok Gupta",
Desigination = "Snr Software Engineer"
},
new WebServiceMonoData()
{
Name = "Jasdeep Singh",
Desigination = "Snr Auditor (Information)"
},
new WebServiceMonoData()
{
Name = "Ashish Srivastava",
Desigination = "Software Test Engineer"
},
new WebServiceMonoData()
{
Name = "Hariharan Ramchandran",
Desigination = "Product Architect"
}
};
return lstFragmentDemo;
}
}
Now following is the code of WebServiceMonoData class
[Serializable]
public class WebServiceMonoData
{
public string Name { get; set; }
public string Desigination { get; set; }
}
Since we are sending our class using services over http, we need to make our class
Serializable. Build and compile webservice, so that it would be available for creating
web reference.
-
Now In your mobile application, right click on the Project->Add-> Add Web Reference,
see I marked that in following screenshot
Change web service URL to your local service address which is “http://localhost:61847/MonoDataService.asmx”
in my case. Select framework .Net 2.0 web services and provide reference as “MonoDataService”
- Now add following code in MainActivity file, I will explain the further down
public class MainActivity : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += OnWebserviceRetrievedInformation;
}
void OnWebserviceRetrievedInformation (object sender, EventArgs e)
{
var objMonoAndroidService = new MonoDataService.MonoDataService ();
objMonoAndroidService.BeginGetWebServiceMonoDatas (WebServiceCallBack, objMonoAndroidService);
}
void WebServiceCallBack (IAsyncResult ar)
{
var objMonoAndroidService =
ar.AsyncState as MonoDataService.MonoDataService;
var arrWebServiceMonoDatas =
objMonoAndroidService.EndGetWebServiceMonoDatas (ar);
var lstWebServiceMonoData =
new List<MonoWebService.MonoDataService.WebServiceMonoData>(arrWebServiceMonoDatas);
var mainListView = FindViewById<ListView>(Resource.Id.Main_ListView);
mainListView.Adapter = new ListBaseAdapter (this, lstWebServiceMonoData);
}
}
Above we are doing following
- On button click create the object of the MonoDataService.MonoDataService and invoke
GetWebServiceMonoDatas method asynchronously.
- In the callback function, creating the List of WebServiceMonoData from retrieved
array and passing it to our custom adapter to create ListView. Here is the code
of our custom BaseAadapter derived class.
public class ListBaseAdapter: BaseAdapter<WebServiceMonoData>
{
List<MonoWebService.MonoDataService.WebServiceMonoData> _lstWebServiceMonoData;
Activity _mainActivity;
public ListBaseAdapter (Activity mainActivity,
List<MonoWebService.MonoDataService.WebServiceMonoData> lstWebServiceMonoData)
{
_lstWebServiceMonoData = lstWebServiceMonoData;
_mainActivity = mainActivity;
}
#region implemented abstract members of BaseAdapter
public override long GetItemId (int position)
{
return position;
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
var item = this [position];
if (convertView == null)
convertView = _mainActivity.LayoutInflater.Inflate (Android.Resource.Layout.SimpleListItem2, parent, false);
convertView.FindViewById<TextView> (Android.Resource.Id.Text1).Text
= item.Name;
convertView.FindViewById<TextView> (Android.Resource.Id.Text2).Text
= item.Desigination;
return convertView;
}
public override int Count {
get {
return _lstWebServiceMonoData== null? -1: _lstWebServiceMonoData.Count;
}
}
#endregion
#region implemented abstract members of BaseAdapter
public override WebServiceMonoData this [int index] {
get {
return _lstWebServiceMonoData== null? null: _lstWebServiceMonoData[index];
}
}
#endregion
}
You can learn more about creating custom Base Adapter
here
Now build and run your mobile application, you will see this ugly exception popping up :-
Problem here is that your mobile app trying to find the Web Service in local mobile,
where it’s not present as it present on the development machine. Now to access web service from your emulator you need to use magic IP address 10.0.2.2, instead of LocalHost. Now while creating web service object pass the URL like this :-
void OnWebserviceRetrievedInformation (object sender, EventArgs e)
{
var objMonoAndroidService =
new MonoDataService.MonoDataService ("http://10.0.2.2:61847/MonoDataService.asmx");
objMonoAndroidService.BeginGetWebServiceMonoDatas (WebServiceCallBack, objMonoAndroidService);
}
-
Try again to build and run mobile app, you again encountered exception, this time
it’s due to updating UI control from worker thread.
Now to solve this problem, move these two line under RunOnUiThread
under WebServiceCallBack method like this :-
RunOnUiThread (() => {
var mainListView = FindViewById<ListView> (Resource.Id.Main_ListView);
mainListView.Adapter = new ListBaseAdapter (this, lstWebServiceMonoData);
});
- Now Build and Run the application,
On 4 Inch Screen
| On Button Click |
|
|
Magic IP table
This section text is taken from
here,
word by word.
The virtual router for each instance manages the 10.0.2/24 network address space — all addresses managed by the router are in the form of 10.0.2.<xx>, where <xx> is a number. Addresses within this space are pre-allocated by the emulator/router as follows:
Network Address | Description
|
10.0.2.1 | Router/gateway address
|
10.0.2.2
| Special alias to your host loopback interface (i.e., 127.0.0.1 on your
development machine)
|
10.0.2.3 | First DNS server
|
10.0.2.4 / 10.0.2.5 / 10.0.2.6
| Optional second, third and fourth DNS server (if any)
|
10.0.2.15 | The emulated device's own network/ethernet interface |
127.0.0.1 | The emulated device's own loopback interface |
Points of Interest
I have used MonoAndroid for C# and Xamarin Studio to build this tutorial. Watch out,
if I continue learning it, you can expect more articles coming soon.
Though Xamarin Studio is proprietary software, however they provide free starter
version to built, test and publish android application. I am using same for my learning.
Articles in this series!
Tips/Tricks in this Series
History
- 22-Aug-2013: First Version
- 06-Sept-2013: Updated Tips and Tricks Section
- 10-Oct-2013: Updated Tips and Tricks Section
- 04-Nov-2013: Update Article series
- 22-Nov-2013: Updated other article section