i wrote tthe below method to insert records using threads, but at run time i receive "[SQLITE_BUSY] The database file is locked (database is locked)" error,and i think could be due to conflict
of sqlite statement.
i just want to know i am wusing the executorservice correctly in the "insertRecord" method? is there any other variables shoule have been synchronizedß
code:
public void insertRecord(String nodeID, String lat, String lng, String xmlpath) throws SQLException, ClassNotFoundException {
if (this.isTableExists(this.TABLE_NAME)) {
InsertRun insRun = new InsertRun(this.psInsert, nodeID, lat, lng, xmlpath);
this.executor.execute(insRun);
} else {
Log.e(TAG, "insertRecord", "table: ["+this.TABLE_NAME+"] does not exist");
}
}
public void flush() throws SQLException {
this.psInsert.executeBatch();
this.psInsert.close();
this.connInsert.close();
Log.d(TAG, "insertRecord", "the rest of the records flushed into data base table.");
}
private class InsertRun implements Runnable {
private PreparedStatement psInsert = null;
private String nodeID;
private String lat;
private String lng;
private String xmlPath;
public InsertRun(PreparedStatement psInsert, String nodeID, String lat, String lng, String xmlpath) {
// TODO Auto-generated constructor stub
this.psInsert = psInsert;
this.nodeID = nodeID;
this.lat = lat;
this.lng = lng;
this.xmlPath = xmlpath;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
this.psInsert.setString(1, this.nodeID);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.setString(2, this.lat);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.setString(3, this.lng);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
this.psInsert.setString(4, this.xmlPath);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.psInsert.addBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(this) {
if (++batchCnt == SysConsts.BATCH_SIZE) {
try {
this.psInsert.executeBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
batchCnt = 0;
Log.d(TAG, "InsertRun", SysConsts.BATCH_SIZE+" records inserted.");
}
}
}
}
SQLite is not a database suitable for concurrent access. You cannot modify your database concurrently:
Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.
.
When SQLite tries to access a file that is locked by another process, the default behavior is to return SQLITE_BUSY
Read this for details (and simply give up multithreading in your app...)
Additionally, good concurrency design considerations can be difficult to offer without know alot more about the program. Suggest perusing through Java Concurrency in Practice if you plan on writing more multi-threaded applications.
Related
Below is code for which i'm trying to write text case and added what i did but getting null pointer exp
public boolean doVersionLimitCheck(Long mneId) throws DMMException {
CALogUtil.getInstance().logMethodEntry("doVersionLimitCheck",
ConfigArchiveManagerImpl.class.getName());
boolean status = false;
status = validateArchivedVersions(mneId);
CALogUtil.getInstance().logDebug("Version Roll over status::" + status);
CALogUtil.getInstance().logMethodExit("doVersionLimitCheck",
ConfigArchiveManagerImpl.class.getName());
return status;
}
for this i did like below.
#Test
public void testDoVersionLimitCheck() {
Long mneId=Long.valueOf("123");
ConfigArchiveManagerImpl impl = new ConfigArchiveManagerImpl();
try {
Mockito.doReturn(true).when(Mockito.mock(ConfigArchiveManagerImpl.class)).validateArchivedVersions(Mockito.anyLong());
} catch (DMMException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
impl.doVersionLimitCheck(mneId);
} catch (DMMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need to spy on the SUT in order to test one method and mock the other:
#Test
public void testDoVersionLimitCheck() {
Long mneId=Long.valueOf("123");
ConfigArchiveManagerImpl impl = Mockito.spy(new ConfigArchiveManagerImpl());
try {
Mockito.doReturn(true).when(impl ).validateArchivedVersions(Mockito.anyLong());
} catch (DMMException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
i am facing a problem regrading specifying the return data type. I have the FOComp class which implements callabale, the call() method of the 'FOComp' returns data type List<ArrayList<Mat>> as shown in the code of 'FOComp' class below.
and the method 'getResults()' returns data of type ArrayList<Mat> as shown in the code below. and currently, at run time, when I execute the code, I receive the folowing error:
Multiple markers at this line
The return type is incompatible with Callable<ArrayList<Mat>>.call()
The return type is incompatible with Callable<List<Mat>>.call()
kindly please let me know how to fix it.
'FOComp' class:
static class FOComp implements Callable<List<Mat>> {//should return list contains 4 mats(0,45,90,135)
private ArrayList<Mat> gaussianMatList = null;
private List<ArrayList<Mat>> results_4OrientAngles_List = null;
public FOComp(ArrayList<Mat> gaussianMatList) {
// TODO Auto-generated constructor stub
this.gaussianMatList = gaussianMatList;
this.results_4OrientAngles_List = new ArrayList<ArrayList<Mat>>();
}
public List<ArrayList<Mat>> call() throws Exception {
// TODO Auto-generated method stub
try {
featOrient = new FeatOrientation(this.gaussianMatList);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
featOrient.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.results_4OrientAngles_List.add(featOrient.getResults());
return results_4OrientAngles_List;
}
}
'getResults':
public ArrayList<Mat> getResults() {
if (this.crossAddOrientMapsList != null) {
if (!this.crossAddOrientMapsList.isEmpty()) {
if (this.crossAddOrientMapsList.size() == 4) {
double[] theta = new double[4];
theta[0] = 0;
theta[1] = 45;
theta[2] = 90;
theta[3] = 135;
for (int i = 0; i < this.crossAddOrientMapsList.size(); i++) {
MatFactory.writeMat(FilePathUtils.newOutputPath("FinalCrossAdd_" + theta[i]+"_degs"), this.crossAddOrientMapsList.get(i));
//ImageUtils.showMat(this.crossAddOrientMapsList.get(i), "OrientMap_" + theta[i] + " degs");
}
return this.crossAddOrientMapsList;
} else {
Log.WTF(TAG, "getResults", "crossAddOrientMapsList != 4 !!");
return null;
}
} else {
Log.E(TAG, "getResults", "crossAddOrientMapsList is empty.");
return null;
}
} else {
Log.E(TAG, "getResults", "crossAddOrientMapsList is null");
return null;
}
}
class FOComp implements Callable<List<Mat>>
and
public List<ArrayList<Mat>> call()
aren't really compatible... Your call() method should be
#Override public List<Mat> call()
Also, it is good practice to avoid implementation classes in method signatures, use the interfaces instead (in this case, use List rather than ArrayList). That will also fix your problem with one of the "multiple markers" :-)
Cheers,
You class declaration says that you are going to return a List of Mat (FOComp implements Callable<List<Mat>>), but your call method signature says you are going to return a List of ArrayList of Mat (List<ArrayList<Mat>>).
You will need to make them consistent.
I have an API that I use to retrieve daily schedules on the live cable-tv for various channels. I have a scenario in which I need a guidance as to which approach should work here.
Lets say I need schedules for 10 different channels from the API.
Should I execute 10 different async tasks for the retrieval of the required data?
Problem:
How would I collect the data in an arraylist and return it once all execution is completed?
How will I access the arraylist in my main function once onpostexecute returns the result?
Or I should just provide the list of channels to my single async task and make it build a single output of arraylist for my main function invoking it?
Problem:
Since I will be accessing a webservice for this purpose, will it make it run slow as compared to my 1st approach?
Second problem with this approach is the same as I am having with my 1st one, I need to know when and how to get the complete resultset once the execution of the task is completed?
Here is some code to explain the problem:
//going with the first approach
//invoking my asynctask from an activity or another class
//I need a global arraylist which I can use after postexecute returns its result
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
for (int i = 0; i < channels.size(); ++i){
AsyncInvokeURLTask task = null;
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override
public void onPostExecute(String result) {
// TODO Auto-generated method stub
try {
//Need to add results to arraylist here...But cannot know when it ends completely
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
Please let me know if something is not clear or missing.
Launching 10 AsyncTask is perfectly fine.
You can keep a count of the number of pending requests. As OnPostExecute is run on the UI thread there are no risks of race condition.
private int numberOfPendingRequests;
public void MyFunc() {
ArrayList<String> channels = channelManager.getAllChannelsByRegion("xyz");
final ArrayList<ChannelSchedule> schedules = new ArrayList<ChannelSchedule>();
final ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
numberOfPendingRequests = channels.size();
for (int i = 0; i < channels.size(); ++i) {
schedules.add(null);
}
for (int i = 0; i < channels.size(); ++i) {
AsyncInvokeURLTask task = null;
final int index = i; // final so it can be used in the onPostExecute.
try {
task = new AsyncInvokeURLTask(
channels.get(i), context, new AsyncInvokeURLTask.OnPostExecuteListener() {
#Override public void onPostExecute(String result) {
try {
ChannelSchedule schedule = mapper.readValue(result, ChannelSchedule.class);
Log.v("channel name", schedule.getChannelName());
Log.v("channel date", schedule.getDate());
Log.v("channel thumb", schedule.getListOfShows().get(0).getShowThumb());
Log.v("channel time", schedule.getListOfShows().get(0).getShowTime());
schedules.set(index, schedule);
numberOfPendingRequests--;
if (numberOfPendingRequests == 0) {
// Everything is received, do stuff here.
}
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.execute();
}
}
I'm trying to load the radio version of the Android device using reflection. I need to do this because my SDK supports back to API 7, but Build.RADIO was added in API 8, and Build.getRadioVersion() was added in API 14.
// This line executes fine, but is deprecated in API 14
String radioVersion = Build.RADIO;
// This line executes fine, but is deprecated in API 14
String radioVersion = (String) Build.class.getField("RADIO").get(null);
// This line executes fine.
String radioVersion = Build.getRadioVersion();
// This line throws a MethodNotFoundException.
Method method = Build.class.getMethod("getRadioVersion", String.class);
// The rest of the attempt to call getRadioVersion().
String radioVersion = method.invoke(null).toString();
I'm probably doing something wrong here. Any ideas?
Try this:
try {
Method getRadioVersion = Build.class.getMethod("getRadioVersion");
if (getRadioVersion != null) {
try {
String version = (String) getRadioVersion.invoke(Build.class);
// Add your implementation here
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Log.wtf(TAG, "getMethod returned null");
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
What Build.getRadioVersion() actually does is return the value of gsm.version.baseband system property. Check Build and TelephonyProperties sources:
static final String PROPERTY_BASEBAND_VERSION = "gsm.version.baseband";
public static String getRadioVersion() {
return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION, null);
}
According to AndroidXref this property is available even in API 4. Thus you may get it on any version of Android through SystemProperties using the reflection:
public static String getRadioVersion() {
return getSystemProperty("gsm.version.baseband");
}
// reflection helper methods
static String getSystemProperty(String propName) {
Class<?> clsSystemProperties = tryClassForName("android.os.SystemProperties");
Method mtdGet = tryGetMethod(clsSystemProperties, "get", String.class);
return tryInvoke(mtdGet, null, propName);
}
static Class<?> tryClassForName(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
return null;
}
}
static Method tryGetMethod(Class<?> cls, String name, Class<?>... parameterTypes) {
try {
return cls.getDeclaredMethod(name, parameterTypes);
} catch (Exception e) {
return null;
}
}
static <T> T tryInvoke(Method m, Object object, Object... args) {
try {
return (T) m.invoke(object, args);
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getTargetException());
} catch (Exception e) {
return null;
}
}
My Android App needs some basic data to run. This data is downloaded from a server using JSON. In Xcode I simply used the sendsynchronous request but I noticed that Eclipse gives me a error when i do networking on the main ui.
Found a lot of stuff on asynctask but i want my app to wait till the required data is downloaded (synchronous?).
I tried using asynctask .execute().get() and setting the variables in onPostExecute but when I return the variable I get a NullPointerException. Does someone know how to make this work? I really need this data before the app can run so I want my app to wait till the data is downloaded.
MainActivity calls this:
SingletonClass appIDSingleton = SingletonClass.getInstance();
this.ID = appIDSingleton.getAppID();
Singleton Class:
public String getAppID() {
try {
new DownloadAppID().execute(APP_ID_URL).get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return AppID; //AppID is still NULL (because the download isnt finished yet?)
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
AppID = result;
}
}
You need to understand that your getAppID method can't return a result that is going to be computed asynchronously.
You could for instance provide a listener to your async task in order to notify when app ID is available:
SingletonClass appIDSingleton = SingletonClass.getInstance();
appIDSingleton.getAppID(new AppIdDownloadListener() {
#Override
public void appIDAvailable(String appId) {
this.ID = appId;
}
});
public void getAppID(AppIdDownloadListener listener) {
try {
new DownloadAppID(listener).execute(APP_ID_URL).get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public interface AppIdDownloadListener {
public void appIDAvailable(String appId);
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
private AppIdDownloadListener listener;
public DownloadAppID(AppIdDownloadListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(String... params) {
/* Your stuff here */
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
listener.appIDAvailable(result);
}
}