使用OData WCF的Android应用程序 - Android应用程序不断崩溃

时间:2013-01-31 07:35:35

标签: java android wcf iis odata

我是Android开发的新手,我正在尝试创建一个应用程序,显示清单列表以进行验证。

由于我是新手,我按照“OData Programming Cookbook for .NET Developers”一书中的一个示例来开发此应用程序的原型。我已经在书中测试了这个例子(第5章)(它运行正常),但由于某种原因它崩溃了。

我怀疑它可能与我的WCF OData服务有关。它是在Entity Framework中开发的,托管在我的本地PC上,即http:192.168.0.105:8090 / PODDataService.svc。

根据本书的例子,我还创建了2个映射类,因为应用程序只与2个OData实体进行交互。

以下是我用来构建项目的6个类:

package com.podcheck;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.core4j.Enumerable;
import org.odata4j.consumer.ODataConsumer;
import org.odata4j.core.OEntity;
import org.odata4j.core.OLink;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListView lvManifests = (ListView)findViewById(R.id.lvManifests);

        // Add item click action listener
        lvManifests.setOnItemClickListener(
                new ManifestListItemClickListener(this)
        );

        // Populate category items on lstCategory
        ArrayList<ManifestObj> manifestList = GetManifestItems();
        ManifestsAdapter mAdapter = new ManifestsAdapter(this, R.layout.list_item, manifestList);
        lvManifests.setAdapter(mAdapter);
    }

    // Query Category list from Northwind based WCF DataService
    ArrayList<ManifestObj> GetManifestItems()
    {
        String svcUri = "http://192.168.0.105:8090/PODDataService.svc/";
        ODataConsumer c = ODataConsumer.create(svcUri);        

        ArrayList<ManifestObj> manifestList = new ArrayList<ManifestObj>();

        Enumerable<OEntity> cursor = c.getEntities("Manifests").expand("ManifestItems").execute();
        for (OEntity entityObj : cursor) 
        { 
            ManifestObj mObj = new ManifestObj();

            mObj.ManifestID =  entityObj.getProperty("ManifestID", Integer.class).getValue();
            mObj.ManifestCode = entityObj.getProperty("ManifestCode", String.class).getValue();
            mObj.ManifestDate = entityObj.getProperty("ManifestDate", Date.class).getValue();

            Date date = new Date();
            if(mObj.ManifestDate == date)
            {

                List<OEntity> entityList = entityObj.getLink("ManifestItems", OLink.class).getRelatedEntities();
                mObj.ManifestItems = new ArrayList<ManifestItemObj>();

                for(OEntity pEntity: entityList) 
                {
                    ManifestItemObj miObj = new ManifestItemObj();
                    miObj.JobType = pEntity.getProperty("JobType", String.class).getValue();
                    miObj.FKID = pEntity.getProperty("FKID", Integer.class).getValue();
                    //miObj.SupplierID = pEntity.getProperty("SupplierID", Integer.class).getValue();
                    //miObj.UnitPrice =  pEntity.getProperty("UnitPrice", BigDecimal.class).getValue();
                    mObj.ManifestItems.add(miObj);
                }
                manifestList.add(mObj);
            }
        }
            return manifestList;
    }


    public void ShowItemsOfManifest(ManifestObj manifest)
    {
        Bundle bundle = new Bundle();
        Intent newIntent = new Intent(this.getApplicationContext(), SubActivity.class);
        newIntent.putExtras(bundle);
        newIntent.putExtra("Manifest", manifest);

        this.startActivity(newIntent);

    }

}

package com.podcheck;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class SubActivity extends Activity implements OnClickListener {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sub);

        ManifestObj mObj = (ManifestObj)this.getIntent().getSerializableExtra("Manifest");

        TextView tv = (TextView)this.findViewById(R.id.tvContent);  

        StringBuffer sb = new StringBuffer();
        sb.append("You have selected the following Category:");
        sb.append("\nManifest: " + mObj.getManifestCode());
        sb.append("\nManifest Raised On: " + mObj.getManifestDate());
        sb.append("\nItems under this Manifest(" + mObj.ManifestItems.size() + "):");
        sb.append("\n----------------------------------------------------------");

        for(ManifestItemObj miObj: mObj.ManifestItems){
            sb.append("\nJob:" + miObj.getJobType() + Integer.toString(miObj.getFKID()));
            sb.append("\n\t");
        }

        tv.setText(sb.toString());

        Button btn = (Button)this.findViewById(R.id.btnReturn);
        btn.setOnClickListener(
            this
        );
    }


    public void onClick(View v) {
        //this.finishActivity(0);
        System.out.println("finish activity");
        this.finish();
    }

package com.podcheck;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;


public class ManifestsAdapter extends ArrayAdapter<ManifestObj> {

    int resourceId = 0;

    public ManifestsAdapter(Context context, int resource, ArrayList<ManifestObj> items) {
        super(context, resource, items);
        this.resourceId = resource;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        LinearLayout itemRoot;
        ManifestObj manifest;

        manifest = this.getItem(position);

        //Inflate the view
        if(convertView==null)
        {
            itemRoot = new LinearLayout(getContext());
            String inflater = Context.LAYOUT_INFLATER_SERVICE;
            LayoutInflater vi;
            vi = (LayoutInflater)getContext().getSystemService(inflater);
            vi.inflate(this.resourceId, itemRoot, true);
        }
        else
        {
            itemRoot = (LinearLayout) convertView;
        }

        TextView tvName =(TextView)itemRoot.findViewById(R.id.tvCategoryName); 
        tvName.setText(manifest.getManifestCode());
        itemRoot.setTag(manifest);

        return itemRoot;
    }

}

package com.podcheck;

//import android.content.Intent;
//import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;

public class ManifestListItemClickListener implements OnItemClickListener {

    MainActivity _mainActivity;
    public ManifestListItemClickListener(MainActivity ma){
        _mainActivity = ma;
    }

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        LinearLayout itemRoot = (LinearLayout)view;
        ManifestObj mObj = (ManifestObj)itemRoot.getTag();

        StringBuffer sb = new StringBuffer();
        sb.append("You have selected the following Manifest:");
        sb.append("\nID: " + mObj.getManifestID());
        sb.append("\nName: " + mObj.getManifestCode());
        sb.append("\nManifestDate: " + mObj.getManifestDate());

//      new AlertDialog.Builder(parent.getContext())
//      .setTitle("Manifest Selected")
//      .setMessage(sb.toString())
//      .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
//          public void onClick(DialogInterface dialog, int which) { 
//              // do something else
//      
//          }
//       })
//       .show();

        _mainActivity.ShowItemsOfManifest(mObj);
    }


}

package com.podcheck;

import java.io.Serializable;

public class ManifestItemObj implements Serializable
{
    int ManifestItemID;
    int FKID;
    String JobType;

    public int getManifestItemsID()
    {
        return ManifestItemID;
    }

    public void setManifestItemID(int manifestItemID)
    {
        ManifestItemID = manifestItemID;
    }

    public int getFKID()
    {
        return FKID;
    }
    public void setFKID(int fkid)
    {
        FKID = fkid;
    }
    public String getJobType()
    {
        return JobType;
    }
    public void setJobType(String jobType)
    {
        JobType = jobType;
    }



}

package com.podcheck;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

import org.joda.time.DateTime;

public class ManifestObj implements Serializable{

    int ManifestID;
    String ManifestCode;
    Date ManifestDate;
    boolean Consolidated;
    ArrayList<ManifestItemObj> ManifestItems;

    public int getManifestID() {
        return ManifestID;
    }
    public void setManifestID(int manifestID) {
        ManifestID = manifestID;
    }
    public String getManifestCode() {
        return ManifestCode;
    }
    public void setManifestCode(String manifestCode) {
        ManifestCode = manifestCode;
    }
    public Date getManifestDate() {
        return ManifestDate;
    }
    public void setManifestDate(Date manifestDate) {
        ManifestDate = manifestDate;
    }
    public boolean getConsolidated() {
        return Consolidated;
    }
    public void setConsolidated(boolean consolidated) {
        Consolidated = consolidated;
    }

    public ArrayList<ManifestItemObj> ManifestItems()
    {
        return ManifestItems;
    }

    public void setManifestItems(ArrayList<ManifestItemObj> manifestItems)
    {
        ManifestItems = manifestItems;
    }
}

此时我认为它与我的Manifest或我的XML文件无关。

我有点失落,因为几乎没有什么不同。我已经无数次地测试了我的WCF数据服务。

它也可以是数据集大小吗? SQL Server DB中的My Manifest表确实有近31000条记录。

编辑:这是日志: -

'02-03 23:11:20.609: D/dalvikvm(617): GC_CONCURRENT freed 272K, 4% free 8197K/8519K, paused 33ms+5ms, total 79ms
02-03 23:11:20.609: D/dalvikvm(617): WAIT_FOR_CONCURRENT_GC blocked 32ms
02-03 23:11:20.769: D/AndroidRuntime(617): Shutting down VM
02-03 23:11:20.780: W/dalvikvm(617): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
02-03 23:11:20.809: E/AndroidRuntime(617): FATAL EXCEPTION: main
02-03 23:11:20.809: E/AndroidRuntime(617): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.podcheck/com.podcheck.MainActivity}: com.sun.jersey.api.client.ClientHandlerException: android.os.NetworkOnMainThreadException
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.os.Looper.loop(Looper.java:137)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread.main(ActivityThread.java:4745)
02-03 23:11:20.809: E/AndroidRuntime(617):  at java.lang.reflect.Method.invokeNative(Native Method)
02-03 23:11:20.809: E/AndroidRuntime(617):  at java.lang.reflect.Method.invoke(Method.java:511)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-03 23:11:20.809: E/AndroidRuntime(617):  at dalvik.system.NativeStart.main(Native Method)
02-03 23:11:20.809: E/AndroidRuntime(617): Caused by: com.sun.jersey.api.client.ClientHandlerException: android.os.NetworkOnMainThreadException
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.api.client.Client.handle(Client.java:457)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.api.client.WebResource$Builder.method(WebResource.java:539)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataClient.doRequest(ODataClient.java:214)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataClient.getMetadata(ODataClient.java:66)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer$CachedEdmDataServices.refreshDelegate(ODataConsumer.java:592)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer$CachedEdmDataServices.getDelegate(ODataConsumer.java:586)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.internal.EdmDataServicesDecorator.findEdmEntitySet(EdmDataServicesDecorator.java:46)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer$CachedEdmDataServices.findEdmEntitySet(ODataConsumer.java:598)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer.getFeedCustomizationMapping(ODataConsumer.java:559)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer.getEntities(ODataConsumer.java:313)
02-03 23:11:20.809: E/AndroidRuntime(617):  at org.odata4j.consumer.ODataConsumer.getEntities(ODataConsumer.java:300)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.podcheck.MainActivity.GetManifestItems(MainActivity.java:46)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.podcheck.MainActivity.onCreate(MainActivity.java:33)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.Activity.performCreate(Activity.java:5008)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
02-03 23:11:20.809: E/AndroidRuntime(617):  ... 11 more
02-03 23:11:20.809: E/AndroidRuntime(617): Caused by: android.os.NetworkOnMainThreadException
02-03 23:11:20.809: E/AndroidRuntime(617):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.io.IoBridge.connect(IoBridge.java:112)
02-03 23:11:20.809: E/AndroidRuntime(617):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
02-03 23:11:20.809: E/AndroidRuntime(617):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
02-03 23:11:20.809: E/AndroidRuntime(617):  at java.net.Socket.connect(Socket.java:842)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:76)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:341)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpConnection.connect(HttpConnection.java:117)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpEngine.connect(HttpEngine.java:310)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
02-03 23:11:20.809: E/AndroidRuntime(617):  at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:215)
02-03 23:11:20.809: E/AndroidRuntime(617):  at com.sun.jersey.client.urlconnection.URLConnect
02-03 23:11:20.839: D/dalvikvm(617): GC_CONCURRENT freed 463K, 6% free 8261K/8775K, paused 25ms+6ms, total 91ms
02-03 23:11:20.839: D/dalvikvm(617): WAIT_FOR_CONCURRENT_GC blocked 14ms'

编辑:

我怀疑这是现在的问题: -

ODataConsumer c = ODataJerseyConsumer.create("http://192.168.0.105:8090/PODDataService.svc"); 

for (OEntity entityObj : c.getEntities("Manifests").expand("ManifestItems").execute())
{
//opcode
}

这意味着它没有读取WCF服务。正确?

另一个编辑: 相同的应用程序现在适用于Android 2.3。 Android 4到2.3有何不同?另一个被发现的谜团。

3 个答案:

答案 0 :(得分:2)

如果这仍然是打开并正在读取实际问题是在android 4.0中你无法在主线程上运行网络调用。它将在主线程错误上抛出网络,在android 2.3中你被允许这样做。这就是为什么一个有效,一个没有。您要做的是在异步任务中运行所有网络操作。查看下面的文档。

http://developer.android.com/reference/android/os/AsyncTask.html

答案 1 :(得分:0)

您可以将odata服务与其他odata客户端一起使用吗?尝试odata explorer或tableau或其他客户。请参阅odata.org/ecosystem#consumers

答案 2 :(得分:0)

它在Android 2.3中完美运行。我现在要关闭这个问题。