I need to port a Java project onto an Android smart phone and display the results in an Android application. I am using eclipse with android plugin (Android SDK 20).
Process:
Exported the jar file of the java project.(java version 1.7.0) Imported the jar file in the libs folder of Android Project. Build Path->Configure Build Path-> Add Jars ->Selected from Libs folder->(OK) (even tested with by changing the order of gtna.jar on top of every thing)
So now i can use the methods and classes in the main file of the android project.I pasted the mainfile code from the java project to be run , in onCreate Function under setContentView(); Although I know it will not display any thing on emulator/smartphone at the moment, but i just want to be sure,this code can be run on android.(results should appear in logcat after successful run).Below is the MainActivity.java from the Android Project.
package com.example.rani;
import gtna.graph.Graph;
import gtna.io.graphReader.GtnaGraphReader;
import gtna.io.graphWriter.GtnaGraphWriter;
import gtna.metrics.trust.DisjunctPaths;
import gtna.metrics.trust.TrustMetric;
import gtna.networks.model.wot.WoTModelSimple;
import java.util.Random;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Here is the code for the demo */
int NUMBER_OF_NODES=10;
WoTModelSimple wotModel = new WoTModelSimple(NUMBER_OF_NODES, null);
Graph wotGraph = wotModel.generate();
GtnaGraphWriter writer = new GtnaGraphWriter();
writer.write(wotGraph, "wot-100000.gtna");
// Read WoT graph
GtnaGraphReader reader = new GtnaGraphReader();
Graph wotGraph2 = reader.read("wot-100000.gtna");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create Trust Metric
// SampleSize (1000) does not matter, if we only compute trust between 2 nodes...
TrustMetric tm = new DisjunctPaths(10, false, false, 5, 2);
//TrustMetric tm = new BasicPathLengthThreshold(1000, false, false, 5);
tm.prepareGraph(wotGraph2);
// Draw random nodes
Random rnd = new Random(System.currentTimeMillis());
int node1 = rnd.nextInt(wotGraph.getNodeCount());
int node2 = rnd.nextInt(wotGraph.getNodeCount());
// Calculate Trust
long t0 = System.currentTimeMillis();
boolean trust = tm.computeTrust(wotGraph.getNode(node1), wotGraph.getNode(node2));
long t1 = System.currentTimeMillis();
// Print results
System.out.println("Node A: " + node1);
System.out.println("Node B: " + node2);
if (trust)
System.out.println("Trust: TRUE");
else
System.out.println("Trust: FALSE");
System.out.println("Runtime: " + (t1-t0) + "ms");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
So now when i run it on the emulator or my samsung (4.2.2), it appears on the screen ,Unfortunately Rani has stopped.Following are the errors shown by logcat.There is RuntimeException caused by Null Pointer Exception.
08-20 15:43:24.850: E/AndroidRuntime(532): Caused by: java.lang.NullPointerException
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.Config.init(Config.java:188)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.Config.get(Config.java:62)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.parameter.ParameterList.getNameXY(ParameterList.java:335)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.parameter.ParameterList.getName(ParameterList.java:311)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.parameter.ParameterList.getDescription(ParameterList.java:141)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.networks.Network.getDescription(Network.java:114)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.util.parameter.ParameterList.getDescription(ParameterList.java:115)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.networks.model.wot.WotModel.generate(WotModel.java:124)
08-20 15:43:24.850: E/AndroidRuntime(532): at gtna.networks.model.wot.WoTModelSimple.generate(WoTModelSimple.java:64)
08-20 15:43:24.850: E/AndroidRuntime(532): at com.example.xvz.MainActivity.onCreate(MainActivity.java:32)
08-20 15:43:24.850: E/AndroidRuntime(532): at android.app.Activity.performCreate(Activity.java:4465)
08-20 15:43:24.850: E/AndroidRuntime(532): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
08-20 15:43:24.850: E/AndroidRuntime(532): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
08-20 15:43:24.850: E/AndroidRuntime(532): ... 11 more
So now you all be wondering , what in Config.java which is Null? Let's see just to take you to exact line of error if you double click on logcat. It's basically the for loop in "init" function, which wants the configurable parameters from .properties(file extension) in the Config Folder. This Config.java is in the jar file of the Java project.
package gtna.util;
import gtna.metrics.Metric;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;
import java.util.Vector;
public class Config {
private static Properties properties;
private static HashMap<String, String> overwrite;
private static String defaultConfigFolder = "./config/";
public static String get(String key) {
String temp = null;
if (overwrite != null && (temp = overwrite.get(key)) != null) {
return temp;
}
if (properties == null) {
try {
init();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return properties.getProperty(key);
}
public static Properties getProperties() {
if (Config.properties == null) {
try {
Config.init();
} catch (IOException e) {
e.printStackTrace();
}
}
return Config.properties;
}
public static boolean getBoolean(String key) {
return Boolean.parseBoolean(get(key));
}
public static int getInt(String key) {
return Integer.parseInt(get(key));
}
public static double getDouble(String key) {
return Double.parseDouble(get(key));
}
public static float getFloat(String key) {
return Float.parseFloat(get(key));
}
public static void appendToList(String key, String value) {
String oldValue = Config.get(key);
if (oldValue == null || oldValue.length() == 0) {
Config.overwrite(key, value);
} else if (!oldValue.contains(value)) {
Config.overwrite(key,
oldValue + Config.get("CONFIG_LIST_SEPARATOR") + value);
}
}
public static void overwrite(String key, String value) {
try {
if (properties == null) {
try {
init();
} catch (IOException e) {
e.printStackTrace();
}
}
overwrite.put(key, value);
} catch (NullPointerException e) {
overwrite = new HashMap<String, String>();
overwrite.put(key, value);
}
}
public static void reset(String key) {
if (overwrite != null) {
if (overwrite.containsKey(key)) {
overwrite.remove(key);
}
}
}
public static void resetAll() {
overwrite = new HashMap<String, String>();
}
public static void addFile(String file) throws IOException {
if (properties == null) {
// System.out.println("initializing with " + file);
properties = new java.util.Properties();
FileInputStream in = new FileInputStream(file);
properties.load(in);
} else {
// System.out.println("adding " + file);
Properties temp = new java.util.Properties();
FileInputStream in = new FileInputStream(file);
temp.load(in);
properties.putAll(temp);
}
}
public static void initWithFiles(String[] file) throws IOException {
properties = null;
overwrite = null;
for (int i = 0; i < file.length; i++) {
addFile(file[i]);
}
}
public static void initWithFolders(String[] folders) throws IOException {
Vector<String> v = new Vector<String>();
for (int i = 0; i < folders.length; i++) {
File folder = new File(folders[i]);
File[] list = folder.listFiles();
for (int j = 0; j < list.length; j++) {
if (list[j].isFile()
&& list[j].getAbsolutePath().endsWith(".properties")) {
v.add(list[j].getAbsolutePath());
}
}
}
initWithFiles(Util.toStringArray(v));
}
public static void initWithFile(String file) throws IOException {
initWithFiles(new String[] { file });
}
public static void initWithFolder(String folder) throws IOException {
initWithFolders(new String[] { folder });
}
public static void init() throws IOException {
// initWithFolder(defaultConfigFolder);
Vector<String> v = new Vector<String>();
File folder = new File(defaultConfigFolder);
File[] list = folder.listFiles();
v.add(folder.getAbsolutePath());
for (int j = 0; j < list.length; j++) {
if (list[j].isDirectory() && !list[j].getName().startsWith(".")) {
v.add(list[j].getAbsolutePath());
}
}
initWithFolders(Util.toStringArray(v));
}
public static boolean containsKey(String key) {
return properties.containsKey(key);
}
public static String[] getData(Metric[] metrics) {
int counter = 0;
for (int i = 0; i < metrics.length; i++) {
counter += metrics[i].getDataKeys().length;
}
String[] data = new String[counter];
int index = 0;
for (int i = 0; i < metrics.length; i++) {
String[] keys = metrics[i].getDataKeys();
for (int j = 0; j < keys.length; j++) {
data[index++] = keys[j];
}
}
return data;
}
public static String[][] allKeys(String from, Metric[] metrics) {
// Metric[] metrics = Config.getMetrics();
String[][] keys = new String[metrics.length][];
for (int i = 0; i < metrics.length; i++) {
keys[i] = Config.keys(metrics[i].getKey() + from);
}
return keys;
}
public static String[] keys(String from) {
String[] keys = Config.get(from).split(
Config.get("CONFIG_LIST_SEPARATOR"));
for (int i = 0; i < keys.length; i++) {
keys[i] = keys[i].trim();
}
if (keys.length == 1 && keys[0].length() == 0) {
return new String[] {};
}
return keys;
}
}
This is the weblink for the java project which i want to port in android(https://github.com/gill-gemini/GTNA-WOT).
According to my understanding some how the emulator can't find the Config folder where there are .properties files. But You can see the Config folder in the base directory in the jar file and the in Rani.apk generated using WinRar. So why there is Java.lang NullPointer Exception for that for loop in Config.java?
I have tested all [the solutions on this page] (How can I use external JARs in an Android project? )except one is not working due to some other reason which I want to share as well mentioned below.
Solution # 2 Create a library android project and copy all the sources to the android project. But my bad luck , several java classes use java.awt.color which is not supported by Android. (apis supported in android So i cannot run this project on and create a jar file from it and use it in my android project. This solution was also mentioned by this blog(which i can't post restrictions repo<10)
Conclusion: Can anybody identify what is the exact problem, is it the Config folder which cannot be find emulator/smartphone during the run time? Or it's the java.awt.color which is not supported by android which crashes the application?
If the problem is to find the Config folder and subfolder which contain .properties files during the runtime , how do I solve it?